【问题标题】:Count set of number has the same difference in integer array计数集在整数数组中具有相同的差异
【发布时间】:2018-10-09 01:18:57
【问题描述】:

有一个数组:[1,1,1,1,2,3,4],计算数组中所有相同差异的集合 ※数组中每个集合的差值可以不一样

Way to count one set have same difference:
-1,0,1  -> count = 1 with diff = 1
1,1,1   -> count = 1 with diff = 0
1,2,3,4 -> count = 3 with diff = 1 ([1,2,3],[1,2,3,4],[2,3,4])
0,1     -> not count
0,1,3   -> not count
0,1,1,2 -> not count , althought it has 0,1 and 1,2 with diff = 1 but it is not continous

As the above array  [1,1,1,1,2,3,4] count = 6
There are 6 sets has the same difference value:
 [1,1,1],[1,1,1,1],[1,1,1] with difference = 0
 [1,2,3],[1,2,3,4],[2,3,4] with difference = 1

这是我的蛮力方法 O(n2) 我可以使用带记忆的 DP 来更有效地改进它吗?

 function run(pArray){
      var count = 0;
      var length = pArray.length;
      for(var i = 0;i<length - 2;i++){          
        var nextIdx = i + 1;
        var diff = pArray[nextIdx]-pArray[i];          
        while(true){
          nextIdx ++;
        
          if(nextIdx > length - 1){
            break;
          }    
          if(pArray[nextIdx] - pArray[nextIdx - 1] !== diff){
            break;
          }else{
            count ++;
          }
        }
    }
    
    console.log(count);
    }
    
    run([1,1,1,1,2,3,4]);

【问题讨论】:

  • 请把你的问题说清楚。对数组和差值进行算法的输入是什么?在您的示例中,输入 arr = [1,1,1,1,2,3,4] 和 difference = 1 ?
  • 嗨 SomeDue 我已经更清楚地编辑了问题。输入只是一个整数数组(在纬度线我调用函数 run() 输出是一个计数集
  • 抱歉您的问题还不清楚。 “※差值可以不一样”是什么意思?
  • 我已经用例子解释了更多:“由于上面的数组[1,1,1,1,2,3,4] count = 6 有6个集合具有相同的差异值:[ 1,1,1],[1,1,1,1],[1,1,1] 差 = 0 和 [1,2,3],[1,2,3,4],[2, 3,4] 差异 = 1 "
  • 好的,因此所有元素之间具有相同差异的集合,即 diff(element - element_to_its_left) 对于所有元素都是相同的 - 需要计算在内。现在还有一个问题:为什么不将 [1,1] 算作差异 0 的另一组?

标签: arrays algorithm dynamic-programming


【解决方案1】:

根据您的最新评论,您似乎确实关心数组中元素的顺序。因此不需要对其进行排序,在这种情况下,集合的数量可以评估为零,如 [1,2,1,2,1] 的情况。

在这种情况下,它可以在O(n) 中完成。

想法是:

如果你发现一个匹配的差异增加一个计数变量,更新 结果为结果 = 结果 + 计数。

举个例子[1,1,1,1]。您无需考虑索引 0,1。

取索引 2 看看是否 arr[2] - arr[1] == arr[1] - arr[0] 然后递增 从 0 到 1 计数,将其添加到结果中。

取索引 3 看看是否 arr[3] - arr[2] == arr[2] - arr[1] ,是的 相等,然后将 count 增加到 2 ,将其添加到结果中。现在结果 = 1 + 2 = 3。

只要你得到的元素满足 标准 arr[i] - arr[i-1] == arr[i-1] - arr[i-2] 你不断添加 下一个更高的价值。所以结果 = 1 + 2 + 3 +....i-2 以此类推 给定索引 i

如果您没有找到匹配的差异,请将计数变量重置为零 并重新开始。

注意:我对 Javascript 不太熟悉,但它看起来像:

<div>
    <script>
      function countSets(arr) {
        if (arr === undefined || arr.length < 3) return 0;
        let count = 0;
        let res = 0;
        for (let i = 2; i < arr.length; ++i) {
          if (arr[i] - arr[i - 1] === arr[i - 1] - arr[i - 2]) {
            count++;
          } else {
            count = 0;
          }
          res += count;
        }
        return res;
      }
      console.log("[1, 1, 1] -> " + countSets([1, 1, 1]))
      console.log("[1, 1, 1, 2, 2, 2] -> " + countSets([1, 1, 1, 2, 2, 2]))
      console.log("[1, 1, 1, 2, 3, 4] -> " + countSets([1, 1, 1, 2, 3, 4]))
      console.log("[1, 1, 2, 3, 4, 4, 5, 5] -> " + countSets([1, 1, 2, 3, 4, 4, 5, 5]))
      console.log("[1, 1, 1, 2, 3, 4, 5, 6] -> " + countSets([1, 1, 1, 2, 3, 4, 5, 6]))
      console.log("[1, 2, 1, 2, 1] -> " + countSets([1, 2, 1, 2, 1]))
    </script>
</div>

【讨论】:

  • 谢谢,太好了!但是您不能对数组进行排序,例如 [1,2,1,2,1] 将计数 = 1,但正确答案是 0,因为差异是 1,-1,1,-1 所以它没有计数.
  • 所以连续集的公式具有相同的差异将是: f(n) = (n-2) + (n-3) +...+(n-n) ? . ex [1,2,3,4,5] => f(5) = (5-2) + (5-3 ) + (5-4) + (5-5) = 6
  • 在 JS 是一样的 1 != -1 。我的意思是数组不应该排序,[1,2,1,2,1] -> [1,1,1,2,2] 然后计数将是 1。无论如何谢谢 SomeDude,你怎么知道?起初,我认为有些人认为像斐波那契公式,但它不起作用:(
  • 是的,我刚刚意识到。有趣的。我删除了我之前的评论。您所要做的就是删除 arr.sort(),我也添加了您的测试用例。
猜你喜欢
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多