Javascript 如何解决CountDistinctSlices编码问题

Javascript 如何解决CountDistinctSlices编码问题,javascript,algorithm,Javascript,Algorithm,我正在尝试“CountDistinctSlices”的可变性问题。我尽了最大的努力,得到了30%的分数,所以我试着去看望那些做过这件事的人,以获得见解。基本上,我在回答中没有得到的是使用初始化的seen数组(和M),以及它是如何被使用的,得到它的人可以友好地引导我完成这个代码 这是我没有解释就找到的答案 function solution(M, A) { // write your code in JavaScript (Node.js 8.9.4) let sum = 0;

我正在尝试“CountDistinctSlices”的可变性问题。我尽了最大的努力,得到了30%的分数,所以我试着去看望那些做过这件事的人,以获得见解。基本上,我在回答中没有得到的是使用初始化的
seen
数组(和
M
),以及它是如何被使用的,得到它的人可以友好地引导我完成这个代码

这是我没有解释就找到的答案

function solution(M, A) {
    // write your code in JavaScript (Node.js 8.9.4)
    let sum = 0;
    let front = 0;
    let back = 0;
    const seen = new Array(M+1).fill(false);
    while (front < A.length && back < A.length){
        while (front < A.length && seen[A[front]] !== true){
            sum += (front-back+1);
            seen[A[front]] = true;
            front += 1;
        }
        while (A[back] !== A[front]){
            seen[A[back]] = false;
            back += 1;
        }
        seen[A[back]] = false;
        back += 1;
    }           
    return Math.min(sum, 1000000000);
}
给定一个整数M和一个由N组成的非空数组a 整数,返回不同切片的数目

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

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

A[0] = 3

A[1] = 4

A[2] = 5

A[3] = 5

A[4] = 2
函数应该返回9,如上所述

为以下假设编写有效的算法:

    N is an integer within the range [1..100,000];
    M is an integer within the range [0..100,000];
    each element of array A is an integer within the range [0..M].

让我们先看一下算法:

  • 首先从起点开始遍历,直到找到重复项。现在你有了一个
    range=[back-front]

  • 代码称这个范围为[back,front],其中“back”是开始,“front”是移动指针。 这个范围内有多少个不同的切片?有大小为1、2等的切片。。。。前-后+1,所以它是sum=
    1+2+3+。。。[前-后+1]

  • 既然你遇到了重复的问题,你该怎么办?为了理解,让我们以问题中的例子:
    [3,4,5,5,2]
    。现在
    front
    到达
    5
    。现在我们应该将
    指针带回
    5
    ,但同时也要从集合中删除元素
    3、4、5
    ,因为这些元素可能在当前前端之后出现。因此,
    back
    转到当前由
    front
    指向的
    5

    让我们再举一个例子,
    [1,2,1]
    ,因为前面的
    将到达索引
    2
    处的
    1
    ,因为这是找到的第一个副本。现在
    back
    应该到哪里去?它应该是
    2
    ,因为当您向后移动
    指针时删除集合中的元素时,集合将不会有任何重复

  • 执行此操作,直到
    前端
    到达阵列的末端

您关于
的问题见

如何在数组中找到重复项?可以使用集合,也可以使用布尔数组。我认为在这个问题中,
M
的唯一目的是指定数组中元素可以具有的最大值。因此,代码使用了一个大小为
M
的布尔数组

如果你使用布尔数组,一旦你找到一个值元素,比如说
v
,你就可以说
boolean\u arr[v]=true
,这意味着它被“看见”

或者,您可以在需要时使用一个集合并创建一个新的集合,而无需在每次发现重复的布尔数组时清除整个布尔数组,方法是让JavaScript处理垃圾收集,如下所示(未完全测试):

函数解(M,A){
设和=0;
设front=0;
放回=0;
设集合=新集合();
while(前
非常感谢您的详细解释,我学到了一些东西。您的解决方案在
[1,2,1]
中失败。根据您的alg,答案是4,但应该是5:
(0,0)、(1,1)、(2,2)、(0,1)、(1,2)
。问题是,您的alg错误地设置为前后,从而忽略了部分切片。@fade2black您是对的!我修改了代码并添加了解释。
    N is an integer within the range [1..100,000];
    M is an integer within the range [0..100,000];
    each element of array A is an integer within the range [0..M].
function solution(M, A) {
    let sum = 0;
    let front = 0;
    let back = 0;
    let set = new Set();
    while (front < A.length) {
        while (front < A.length && !set.has(A[front])){
            sum += (front-back+1);
            set.add(A[front]);
            front += 1;
        }
        while (A[back] != A[front]) {
            set.delete(A[back]);
            back += 1;
        }
        set.delete(A[back]);
        back += 1;
    }           
    return Math.min(sum, 1000000000);
}