在线性时间内查找长度为 N、数字 1 到 N-1 的数组中的重复项,而无需使用额外的 obj/arr 来跟踪计数

Posted

技术标签:

【中文标题】在线性时间内查找长度为 N、数字 1 到 N-1 的数组中的重复项,而无需使用额外的 obj/arr 来跟踪计数【英文标题】:Find, in linear time, duplicate in array of length N, numbers 1 to N-1 without using additional obj/arr to keep track of a count 【发布时间】:2021-08-21 14:58:28 【问题描述】:

我能够在线性时间和空间内完成这个 edabit 挑战,但挑战表明它只能使用相同的数组来完成(不需要额外的 obj/arr 来跟踪“已经看到”的数字。) 线性时间

约束:长度为 'n' 的列表和范围从 1 到 n-1 的数字

// length N
// 1 to N - 1
const l = [5, 2, 1, 3, 4, 2]

function findDuplicate(list) 
  

我认为这与在数组中的索引处跟踪“已经看到”的数字有关,但如果不需要再次循环遍历数组,我就无法做到这一点。

这就是我能够做到的:

function findDuplicate(list) 
  const dict = 
  for (let i=0; i < list.length; i++) 
    dict[list[i]] = dict[list[i]] + 1 || 1   
    if (dict[list[i]] === 2) return list[i]
  

但我使用obj 来跟踪“已经看到”的数字。

【问题讨论】:

嗯,您可以对数组进行排序,然后从索引 1 开始遍历它。如果数组中的当前数字与 numbers[i - 1] 相同,那么这是您的副本。 对不起,忘了说它需要是线性时间。将其添加到问题中 你可以得到数组元素的总和,然后用n*(n+1)/2(自然数的总和)减去它。 (或者,在这种情况下n*(n-1)/2)。但是,这需要一个变量。这行得通吗? 您的数组中是否只有一个重复项? 只有一个副本 【参考方案1】:

由于您有一个只有一个重复的自然数数组,您可以得到直到n-1 的自然数之和,然后从数组元素的总和中减去它。

(5 + 2 + 1 + 3 + 4 + 2) - (1 + 2 + 3 + 4 + 5) = 2

这是一个sn-p:

function findDuplicate(list) 
  const n = list.length,
        sum = list.reduce((a, b) => a + b, 0),
        naturalSum = n * (n-1) / 2

  return sum - naturalSum


console.log( findDuplicate([5, 2, 1, 3, 4, 2]) )
console.log( findDuplicate([1, 2, 3, 4, 3]) )

如果不允许,您也可以在不使用额外变量的情况下编写它:

function findDuplicate(l) 
  return l.reduce((a, b) => a + b, 0) - (l.length * (l.length - 1) / 2)

【讨论】:

【参考方案2】:
const numbers = [5, 2, 1, 3, 4, 2];
const n = numbers.length - 1;
const expectedSum = (n * (n + 1)) / 2;
const sum = numbers.reduce((acc, val) => acc + val, 0);
const duplicate = sum - expectedSum ;

【讨论】:

【参考方案3】:

也许[5, 2, 1, 3, 4, 2].reduce((acc, num, index) =&gt; (acc + num) - index, 0)

【讨论】:

以上是关于在线性时间内查找长度为 N、数字 1 到 N-1 的数组中的重复项,而无需使用额外的 obj/arr 来跟踪计数的主要内容,如果未能解决你的问题,请参考以下文章

不修改数组找出重复的数字

在线性时间内对 0 到 n^2 – 1 范围内的 n 个数字进行排序

查找数组中重复的数字

剑指offer_查找数组中的任一重复元素

长度为n值域为[0,n-1]的数组中重复的数字

面试题3:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为