计算每个大小为k * k的窗口中的不同元素

时间:2017-11-07 19:26:46

标签: algorithm multidimensional-array sliding-window

我发现了这个:http://www.geeksforgeeks.org/count-distinct-elements-in-every-window-of-size-k/

  

给定一个大小为n且整数为k的数组,返回大小为k的所有窗口中不同数字的计数。
  (...)
  高效的解决方案是在滑动窗口时使用先前窗口的计数。我们的想法是创建一个存储当前寡妇元素的哈希映射。当我们滑动窗口时,我们从哈希中删除一个元素并添加一个元素。我们还跟踪不同的元素。

但对于二维数组和大小为k * k的窗口,是否有一个高效的解决方案?

2 个答案:

答案 0 :(得分:0)

优化的解决方案在很大程度上取决于您的价值重新分配(如果您有大量的冗余或减少了可能性)。 将您之前在 existing_values [] 表中找到的唯一数字存储起来并检查其中已存在的内容可能会很有趣:

对于窗口中的每个新值:

检查该值是否在 existing_values []

  • 否:在 existing_values [] 表中添加值并增加 dist_count
  • 是:没什么

答案 1 :(得分:0)

检查二维数组中所有k×k个正方形的属性的一般方法是将所有矩形的属性从左上角存储到每个单元格,然后比较单元格的属性。要检查的矩形的四个角。

考虑这个示例数组,其值为0到9:

1 8 5 6 8  
7 2 5 4 6  
3 0 2 5 8  
9 5 1 4 6  

一个哈希数组,用于存储从左上角到每个单元格的矩形中每个0-9值的出现次数:

0100000000  0100000010  0100010010  0100011010  0100011020
0100000100  0110000110  0110020110  0110121110  0110122120
0101000100  1111000110  1121020110  1121131110  1121132130
0101000101  1111010111  1221030111  1221241111  1221243131

如果你从左上角到右下角构建它,每个散列都是它上面的散列和它左边的散列的总和,减去它左上方的散列,以及单元格的值添加;例如cell(1,1)的散列基于单元格(1,0),(0,1),(0,0)及其自身值2的散列:

0100000010 + 0100000100 - 0100000000 + 0010000000 = 0110000110  

一旦有了哈希数组,就可以使用角落处的哈希来检查任何矩形,例如:检查这个矩形:

. . . . .  
. 2 5 4 .  
. 0 2 5 .  
. . . . .  

你在这些位置采取哈希:

A . . B .  
. . . . .  
C . . D .  
. . . . .  

并且矩形的散列是D-B-C + A:

1121131110 - 0100011010 - 0101000100 + 0100000000 = 1020120000

表示矩形有一个0,两个2,一个4和两个5,所以有两个不同的元素:0和4.

构建散列数组意味着计算m×n个散列(其中m×n是数组的大小),每个散列基于三个其他散列,并且检查每个k×k平方意味着计算(mk)×(nk)散列,每个都基于四个哈希。这是否意味着时间复杂度实际上是O(m×n)可能取决于值的范围和相应的散列大小。