【问题标题】:2d array, all values are adjacent二维数组,所有值都是相邻的
【发布时间】:2015-09-28 02:46:18
【问题描述】:

我需要一种快速的方法来检查二维数组是否完全相邻,这意味着所有值都与其他相同的值相邻。相邻的意思是四个主要方向。

This would be an adjacent array
[1 1 2]
[1 2 2]
[3 3 3]

This isn't
[1 2 1]
[1 2 2]
[3 3 3]

This is
[1 2 4]
[1 2 2]
[3 3 3]

到目前为止,我已经尝试了一种 O(M * N) 方法,在该方法中我遍历整个数组并检查是否至少有一个邻居是相同的值。我正在寻找一种可能更快的方法。

编辑:刚刚注意到我的方法甚至无法正常工作。例如:

This should fail (not all of the 1s are adjacent)
[1 2 1]
[1 2 1]
[3 3 3]

所以现在我需要一个实际的算法。

【问题讨论】:

  • 我不认为你可以比这里的 O(width*height) 做得更好。至少,您需要访问每个单元至少两次。
  • 我们在谈论哪些维度?您想将此算法应用于 50x50 或更大的数组吗?
  • @TimHallyburton 很小。最大约 10x10

标签: algorithm matrix multidimensional-array


【解决方案1】:

我想起了扫雷游戏。

  1. 外循环:扫描整个数组(逐行,从左到右)。 这是为了找到内循环的下一个位置。如果我们有 没有从内循环访问过这个位置,并且数字在 这个位置还没有看到,在这个位置开始内循环 位置。如果我们已经看到这个位置的数字,那么 矩阵不是“相邻的”。

  2. 内循环:查找所有相邻的具有相同编号的单元格并标记 他们被访问(扫雷部分)。将此号码记录为 访问并返回外循环。

这需要一个显示“已访问”位置的布尔矩阵(与被扫描的数组大小相同)和已“访问”的数字 [1..n] 的布尔列表。

【讨论】:

    【解决方案2】:

    因为,我假设,相似的值可以任意相距很远,并且可以采取任何形状,在矩阵中,如果不首先计算值的连通分量,我看不出你是如何做到的:

    1. 找到矩阵的connected components labeling
    2. 为每个矩阵值保留其所属的组件标签列表。
    3. 如果任何值已经有一个与之关联的标签,停止,矩阵不是“相邻的”。如果没有,则矩阵是“相邻的”。

    【讨论】:

      【解决方案3】:

      我只想提一下,您无法创建比O(M*N) 更好的算法(当然这是最坏情况下的复杂度),因为在最坏情况下您将不得不访问所有元素。

      正如您所说,您的 O(M*N) 算法不适用于所有情况,您可以使用 BFS 和 Time complexity is O(M*N) 解决此问题

      if(no.of connected components == no.of distinct elements) {
          return true;
      }else{
          return false;
      } 
      

      你如何找到连接组件的数量?

           yourFunction(int[][] matrix){
               boolean visited[][];
               for(int i=0;i<m;i++){
                  for(int j=0;j<n;j++){
                     if(!visited[i][j]){
                         BFS(matrix,i,j);
                         connectedComponents++;
                     }
                  }
               }
               int distinctNumbers = findDistinctNumbers(matrix); // you can write this function easily.
           }
          void BFS(int[][] martix, int i,int j){
               queue<Point> queue = new LinkedList<>();
               queue.add(new Point(i,j));
               while(queue.isEmpty()){
                   Point point = queue.poll();
                    for each neighbour of point
                        if neighbour is not visited && neighbour value =current point value
                            add neighbour to queue;
               }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-13
        • 2016-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多