Java 计算不同切片的数量(仅包含唯一的编号)

Java 计算不同切片的数量(仅包含唯一的编号),java,arrays,algorithm,Java,Arrays,Algorithm,我解决了以下提供的协同问题 一个整数M和一个非空数组a,由N个非负数组组成 整数是给定的。数组A中的所有整数都小于或等于 M 一对整数(p,Q),如0≤ P≤ Q=100000000) 返回100000000 如果(已设置为(a)){ 总和+=len*(len+1)/2 len=1 set.clear() }否则{ 莱恩++ 集合。添加(a) } } 总和+=len*(len+1)/2 返回Math.min(总和,100000000) } 变量A=[3,4,5,5,2] console.log(

我解决了以下提供的协同问题

一个整数M和一个非空数组a,由N个非负数组组成 整数是给定的。数组A中的所有整数都小于或等于 M

一对整数(p,Q),如0≤ P≤ Q

例如,考虑整型m=6和数组A,以便:

A[0] = 3
A[1] = 4
A[2] = 5
A[3] = 5
A[4] = 2 There are exactly nine distinct slices: (0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2), (3, 3), (3, 4) and (4, 4).
A[0] = 3
A[1] = 4
A[2] = 5
A[3] = 5
A[4] = 2 the function should return 9, as explained above.
目标是计算不同切片的数量

编写一个函数:

类解决方案{public int Solution(int M,int[]A);}

给定一个整数M和一个由N组成的非空数组a 整数,返回不同切片的数目

如果不同切片的数量大于100000000,则 函数应返回100000000

例如,给定整数M=6和数组A,以便:

A[0] = 3
A[1] = 4
A[2] = 5
A[3] = 5
A[4] = 2 There are exactly nine distinct slices: (0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2), (3, 3), (3, 4) and (4, 4).
A[0] = 3
A[1] = 4
A[2] = 5
A[3] = 5
A[4] = 2 the function should return 9, as explained above.
为以下假设编写有效的算法:

N是[1..100000]范围内的整数;M是内的整数 范围[0..100000];数组A的每个元素都是一个整数 范围为[0..M]

我的解决方案就在这里

public static int solution(int M, int[] A) {

        boolean[] visited = new boolean[M + 1];

        int N = A.length;


        int result = 0;

        for (int i = 0; i < N; i++) {

            int k = i;
            int count = 0;

            while (i < N && !visited[A[i]]) {

                count++;
                visited[A[i]] = true;

                i++;
            }

            i -=1;

            // 3, 4, 5, 5, 2, 5, 4
            int j = i;

            while (j >= k && visited[A[j]]) {

                visited[A[j]] = false;
                j--;
            }

            result += count * (count + 1) / 2;
        }

        return result;
    }
公共静态int解决方案(int M,int[]A){
布尔[]访问=新布尔[M+1];
int N=A.长度;
int结果=0;
对于(int i=0;i=k&&访问[A[j]]{
访问[A[j]]=false;
j--;
}
结果+=计数*(计数+1)/2;
}
返回结果;
}

然而,在线法官对正确性和性能的估计很低。我该如何改进呢?

看来您选择了正确的方法,但在实现细节上犯了错误——在坏主意中减少索引

制作两个索引-左索引和右索引

a) 向右移动,直到满足重复元素(“stopper”)的要求—实际上,您是在第一个while循环中执行此步骤。如果您在停止之前进行了n步,则有n*(n-1)/2个切片

b) 现在向左移动索引,直到找到与“stopper”相同的元素,并在其后停止。现在的片又好了


重复a)和b)直到结束。请注意,这两个索引只向前移动,复杂性是线性的

我喜欢双指针方法的想法,并对MBo阐明的访问数组进行O(1)更新。这里有一个单指针的想法,它使用一个哈希集来实现唯一性,每次新段开始时,该哈希集都会被清除

函数f(A){
var总和=0
变量集=新集
var len=0
为了{
如果(总和>=100000000)
返回100000000
如果(已设置为(a)){
总和+=len*(len+1)/2
len=1
set.clear()
}否则{
莱恩++
集合。添加(a)
}
}
总和+=len*(len+1)/2
返回Math.min(总和,100000000)
}
变量A=[3,4,5,5,2]

console.log(f(A))
好的,我想我错过了指令
如果不同片数大于100000000,函数应该返回100000000。