【问题标题】:Is there a way to loop over an integer array, keeping track of all unique elements WITHOUT allocating a new array?有没有办法循环一个整数数组,在不分配新数组的情况下跟踪所有唯一元素?
【发布时间】:2015-12-28 15:59:56
【问题描述】:

一个数组包含 N 个元素,每个元素都在 1

编辑: 该数组保证包含所有值 1-X。 X 是一个参数,而不是一个常数。

编辑:

更一般地说,我想知道是否有一些已知的方法可以将唯一的连续整数组合成一个和或一个乘积,这样该总和或乘积的值就可以判断这些整数中的一个是否是它的一部分.类似于将唯一素数相乘。

谢谢

【问题讨论】:

  • 我想知道是否有一种方法可以遍历数组,这是个好主意,并且会继续这样做。现在,到目前为止,您尝试了什么?
  • 如果 N
  • 最初我想将所有整数 1-X 映射到一个唯一的素数,并通过将所有素数 1-X 相乘来组成一个主数。然后将主数除以映射的素数。如果那个素数是一个因素,它还没有被看到。如果它不是一个因素,它已经被分开了。但是这个数组可能非常非常大,所以整数溢出将是一个直接的问题,我不知道将整数映射到素数的方法。
  • 您对目标的解释与此问题的标题不符。您的解释与查找唯一元素无关,而是确定数组是否包含至少一个条目,用于每个值 1 到 X
  • 你能改变原始数组吗?如果是这样,答案就在这里stackoverflow.com/questions/5739024/…

标签: arrays algorithm


【解决方案1】:

有一种简单的方法,但效率极低。 只需使用两个嵌套循环。未经测试的伪代码:

   lastIndex = 0;
   containsAll = true;
   for ( i=1; i <= x; i ++ ) {
       for ( j=0; j < n; j++ ) {
          if ( array(j) == i ) {
            if ( j > lastIndex ) {
               lastIndex = j;
            }
            break;
          }
       }
    }

【讨论】:

  • OP 写道“编辑:数组保证包含所有值 1-X”。他想找到包含所有1...X 的数组索引。
  • 和我想的一样。请注意,如果他想深入到他必须搜索的数组以查看所有元素,您可以在代码中轻松跟踪。
  • 好的,我已经修改了答案,找到索引最低的索引。
【解决方案2】:

困难不在于找到数字,而在于记住您已经遇到过哪些数字。这对于知道您何时找到每个数字以及避免多次计算同一个数字很有必要。
我看到了两种方法来确保您至少找到每个数字一次,而无需使用额外的存储空间:

  1. 依次搜索每个数字:搜索 1,然后是 2,然后是 3,然后是 X。(如 FredK 的答案)
  2. 通过将找到的数字移动到位来跟踪找到的数字:将值为 n 的项目移动到位置 n

第二个选项将包括遍历数组,并且对于您遇到的每个值,将其与索引为找到值的项目交​​换。如果该索引处的项目已经具有正确的值,则您之前遇到过该数字。
为避免计数两次,您应该只计算在原位找到的值,或向后移动到原位的值。当您稍后迭代该位置时,将计算向前移动到该位置的值。

【讨论】:

    【解决方案3】:

    你知道 X 是什么 - 所以 sum(1..x) = (x * (x +1))/2

    foreach element in array
    Look back and see if value exists, if no add to sum
    If sum == sum(1..x) - then break
    

    编辑:

    似乎我的伪代码太多要填充..这里是 c# 版本 - idx 以 12 结尾 - 前 6 的位置。数组无序且重复。

      var numbers1 = new int[] { 8, 7, 2, 9, 4, 1, 1, 3, 1, 5, 5, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
      var x = 9;
      var sumxResult = (x * (x + 1)) / 2;
      var idx = 0;
      var sumx = 0;
    
      for (var i = 0; i < numbers1.Length - 1; i++)
      {
        var n = numbers1[i];
        idx = i;
        var found = false;
        //seek back:
        for (var j = i-1; j >= 0; j--)
        {
          var n1 = numbers1[j];
          if (n1 == n)
          { found = true; break; }
        }
    
        if (!found)
        {
          sumx += n;
          if (sumx == sumxResult)
            break;
        }
      }
      Console.WriteLine(idx);
    

    【讨论】:

    • 这适用于已排序的数组,但此数组不一定是已排序的。在这种情况下,元素的索引也是必要的信息,所以我不认为排序是一种选择。
    • 这个想法是您不需要排序 - 将数字相加的顺序无关紧要。您使用 (x*(x-1))/2 来验证您是否已按某种顺序访问过所有 1-x 一次。如果仅对每个 1-x 中的一个进行排序,这将表现最差 - FredK 的解决方案将是最好的。如果对每个 1-x 的多个值无序,这会更好。
    • 我认为您正在寻找 (x*(x+1)/2),但即便如此,这在数组中有重复项的情况下也不起作用。
    • 您的权利 - 输入错误。我添加了一个工作版本 - 因为你看不出我的意思:)
    猜你喜欢
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2016-05-12
    • 2020-04-07
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    相关资源
    最近更新 更多