查找序列中重复项的更好方法,而不是检查其第一个和最后一个索引

时间:2017-10-29 06:05:56

标签: javascript arrays algorithm time-complexity

我正在解决一个challenge,它有一个来自1 to N的整数序列,任务是找到序列中缺少的整数,以及一个重复的整数。

约束 -

  

不允许对数组进行排序。

     

您的解决方案不应超时N值。

     

理想情况下,除了输入数组提供的空间(可以修改)之外,您的解决方案不应使用额外的空间。

我当前的代码超时,我假设是因为查找重复元素的复杂性可能是O(N^2)

对于缺失的元素,我的算法是 -

  1. 创建变量,将其设置为1,循环直到条件为真
  2. 在循环中,检查数组中是否存在变量,如果是,则增加变量并继续循环
  3. 如果在数组中找不到变量,则这是缺少的元素。打破循环。
  4. 这应该在O(N)时间运行,因此这部分应该没问题。

    对于duplicate元素,我的方法是检查数组中每个元素的第一个索引和最后一个索引。对于唯一元素,索引值将是相同的,但对于重复项,它将是不同的。

    我认为这就是问题所在。

    我的代码 -

    function solution(array) {
      var missing = 0,
        duplicate = 0;
      let notFound = true;
      let curr = 1;
      while (notFound) {
        if (array.indexOf(curr) === -1) {
          notFound = false;
          break;
        }
        curr++;
      }
      missing = curr;
    
      duplicate = array.find((e, i, arr) => arr.indexOf(e) !== arr.lastIndexOf(e));
      return [missing, duplicate];
    }
    
    console.log(solution([2, 3, 1, 4, 4, 6]));

    我查看了一些相关问题,例如thisthis,但无法从中获取任何内容。

    我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

我认为你可以哈希你的输入数组。
我的意思是,假设你的阵列是[4,1,5,6,3,1]
这是一个简单的伪代码。
你可以得到这样的重复元素:

for i:array.length
    array[array[i]] = array[i]*-1 // you found and marked first element of your array
    if(array[i] > 0) //it would be positive if you found and marked an element twice.
        array[array[i]] is the duplicate element

这在O(n)

中运行

现在要获取缺少的元素,可以再次遍历数组

for i:array.length
    if (array[i] > 0 && array[i]!=duplicate element) //there would be two positive numbers, missing number and the duplicate
        i = missing element

这个O(n)再次,所以它的O(n)整体。 如果有什么不清楚,你可以问。很抱歉更愿意写一个伪代码而不是解释。