【问题标题】:Finding same numbers in matrix with some conditions在某些条件下在矩阵中找到相同的数字
【发布时间】:2014-12-05 15:51:46
【问题描述】:

我有一个编程比赛的问题。这个问题在某些时候很容易。我写了一个解决方案不是很好。我想听听你对这个问题的看法,你将如何设法在更“好”的编程中解决这种问题。

问题:

编写一个程序,输入一个 N*N 数组。这个数组 包含整数。你应该找到多少个不同的数字 是否存在以下条件:不同的数字也是:

A) 相同但彼此相邻的数字。例如 1 1 可以 被认为是一个数字,因为它们是相同的数字并且在每个数字旁边 其他。

B) (A) 为真,如果你有例如数字 1,那么任何 左、右、上、下的相同数字也相同。

例如

1 1 2 3

1 2 3 4

2 2 1 3

因此,对于上述情况,有 8 个不同的数字。这是因为,在数组 [0,0] 处,[0, 1] 和 [1,0] 可以被认为是一个数字,而不是 3 个不同的数字。 [1,1],[2,1] 因此 [2,0] 也是相同的数字。因此,正如您在最后一个数字中看到的那样,[1,1], [2,1] 确实暗示了条件,然后 [2,0],[2,1] 也暗示了条件,但是因为 [2,1 ] 也暗示了 [1,1] 的条件,因此所有 [1,1]、[2,1] 和 [2,0] 都是一个数字。

我的代码:

public class matrix
{
   public static void main(String[] args)
   {
      int[][] arr = 
      { 
          {1, 2, 3, 4}, 
          {1, 1, 2, 4},
          {5, 6, 2, 2},
      };

      for(int row = 0; row < arr.length; ++row)
      {
         for(int col = 0; col < arr[row].length; ++col)
         {
            //top
            if(row!=0)
            {
               if((arr[row][col] == arr[row-1][col]) || (Math.abs(arr[row][col]) == arr[row-1][col]) || (arr[row][col] == Math.abs(arr[row-1][col])))
               {
                  arr[row-1][col] = -arr[row-1][col];
               }
            }

            //botom
            if(row!=arr.length-1)
            {
               if(arr[row][col] == arr[row+1][col] || Math.abs(arr[row][col]) == arr[row+1][col] || arr[row][col] == Math.abs(arr[row+1][col]))
               {
                  arr[row+1][col] = -arr[row+1][col];
               }
            }

            //left
            if(col!=0)
            {
               if(arr[row][col] == arr[row][col-1] || Math.abs(arr[row][col]) == arr[row][col-1] || arr[row][col] == Math.abs(arr[row][col-1]))
               {
                  arr[row][col-1] = -arr[row][col-1];
               }
            }

            //right
            if(col!=arr[0].length-1)
            {
               if(arr[row][col] == arr[row][col+1] || Math.abs(arr[row][col]) == arr[row][col+1] || arr[row][col] == Math.abs(arr[row][col+1]))
               {
                  arr[row][col+1] = -arr[row][col+1];
               }
            }
         }
      }


      for(int row = 0; row < arr.length; ++row)
      {
         for(int col = 0; col < arr[row].length; ++col)
         {
            System.out.print(arr[row][col] + " ");
         }

         System.out.println();
      }
   }
}

我的逻辑是将相同的数字设置为负数,然后只计算正数以找到不同的数字。
我想要一种不同的算法,它会产生更小的 Big-O 复杂度。

谢谢。

【问题讨论】:

  • 也许我遗漏了一些明显的东西,但您的示例似乎有 8 个不同的数字:([0,0], [0,1], [1,0]), ([1,1], [2,0], [2,1]), ([0,2]), ([0,3]), ([1,2]), ([1,3]), ([2,2]), ([2,3])。另外,当您说您想要“更高级的编程方法”时,您的意思是更好的算法吗?一个更快(更小的 big-O 复杂度)?
  • 是的,没错,我将编辑我的问题。是的,我的意思是更好的算法,更快的算法,但也因为那是面试等问题,我想给人留下深刻印象,所以我想把我的逻辑思维改成更好的。
  • 我之前问过但删除了。你能改写你的第二条规则吗?
  • 嘿,当然。第二条规则说,如果您有一个数字 X,那么要使规则 (A) 为真,您应该拥有 X 数字的左、右、上或下与 X 相等的数字。我不知道这是否更好?
  • 这不是多余的吗?我很困惑,因为我认为(2)只是重申(1)。是否只是在四面八方的手段旁边澄清?

标签: java arrays algorithm


【解决方案1】:

如果我正确理解您的问题,您可以将其视为图形问题,计算连接组件的数量。

例如,使矩阵中的每个条目成为一个顶点(由行列标记),因此 (0,0) 是一个顶点(值为 1)。然后,如果两个顶点在彼此的正上方、下方、右侧或左侧并且具有相同的值,则它们是相邻的。例如,(0,0) 与 (0,1) 相邻,因为两者的值都为 1。(0,1) 与 (0,2) 不相邻,因为第一个值为 1,第二个值为 2。然后你数图中连接组件的数量。每个连接的组件代表一个“不同”的数字。

有很多方法可以快速计算连接组件的数量。例如,从顶点 (0,0) 开始,进行广度优先搜索。您找到的任何顶点都与 (0,0) 位于同一分量中。然后从尚未找到的任何顶点开始重复。广度优先搜索是线性时间,但您必须运行多次(运行次数越多,每次运行速度越快),因此确定准确的渐近运行时间有点复杂。您的输入大小为 n^2(顶点数)。它不会比 n^3 差,并且可能更接近 n^2(请记住,n^2 表示“输入大小呈线性”)。

【讨论】:

  • 也想过同样的事情。这里的主要问题是获取下一个未访问的“节点”。如果我们可以负担 O(n^2) 的额外内存,我建议首先牺牲 O(n^2) 时间来将所有坐标存储在 HashSet 中并从中删除访问过的“节点”。这将为我们提供在 BFS 运行之间获取下一个未访问节点的摊销常数时间。
  • 很酷的解释。谢谢你。是的,这个问题可以被认为是一个图表。我不太了解图论,所以对我进行编程有点痛苦。我必须修改我的图论知识。
猜你喜欢
  • 2021-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多