【问题标题】:Matrix, algorithm interview question矩阵、算法面试题
【发布时间】:2011-03-23 16:50:35
【问题描述】:

这是我的面试问题之一。

我们有一个包含整数的矩阵(未提供范围)。矩阵随机填充整数。我们需要设计一种算法来找到与列完全匹配的那些行。我们需要返回匹配的行号和列号。匹配元素的顺序相同。例如,如果第 i 行与第 j 列匹配,并且第 i 行包含元素 - [1,4,5,6,3]。然后第 j 列也将包含元素 - [1,4,5,6,3]。大小为 n x n。 我的解决方案:

RCEQUAL(A,i1..12,j1..j2)// A is n*n matrix
if(i2-i1==2 && j2-j1==2 && b[n*i1+1..n*i2] has [j1..j2])
   use brute force to check if the rows and columns are same.
if (any rows and columns are same)
   store the row and column numbers in b[1..n^2].//b[1],b[n+2],b[2n+3].. store row no,
                                                 // b[2..n+1] stores columns that 
                                                 //match with row 1, b[n+3..2n+2] 
                                                 //those that match with row 2,etc..

else
   RCEQUAL(A,1..n/2,1..n/2);
   RCEQUAL(A,n/2..n,1..n/2);
   RCEQUAL(A,1..n/2,n/2..n);
   RCEQUAL(A,n/2..n,n/2..n);

花费 O(n^2)。它是否正确?如果正确,是否有更快的算法?

【问题讨论】:

  • 问题 - 如果其中一行是 [1,2,3] 并且其中一列是 [2,3,1] 是否被视为匹配?
  • 不,它们的顺序必须相同。
  • 不是立方吗?如果您将 n 行中的每一行与 n 列中的每一列进行比较,那就是 n*n 比较,并且每次比较的长度可能为 n (最坏情况)。随机数据的平均值可能是 n 平方。
  • 它的 T(n)=4T(n/2)+O(1) 即 O(n^log4)=O(n^2)
  • 对不起,这个问题已经有一段时间没有添加了,但我必须问,这不是n^2吗?您可能会进行 n/2 比较,因此您的重复次数不能为 + O(1)。这里有什么见解/技巧基本上阻止您将每一行与每一列进行比较?

标签: algorithm matrix rows


【解决方案1】:

您可以根据行中的数据构建trie。然后您可以将列与特里树进行比较。

这将允许在列的开头与任何行不匹配时立即退出。这也可以让您一次检查所有行的列。

当然,当n 很大(为小的n 设置一个trie 不值得)并且有很多行和列完全相同时,trie 是最有趣的。但即使在矩阵中所有整数都不同的最坏情况下,该结构也允许使用清晰的算法...

【讨论】:

  • 他说矩阵是随机填充的。特里树利用公共前缀。此外,您仍然需要 O(n*n) 来扫​​描所有数据以创建 trie。
  • @phkahler:你是对的。但是,您一开始可能不会构建 trie。您可以在比较列和行的同时构建特里树。然后 trie 成为一种记忆结构,不需要 O(n*n) 扫描所有行。
  • 想一想,我想出的每个算法都有几乎 O(n*n) 的最差时间。如果整数是真正随机的,trie 将允许过滤掉大多数情况,但如果除最后一行和最后一列之外的所有元素都相等,则有最坏的情况...
  • @Adrien Plisson 我的呢?
  • @nightcracker:我不得不承认,我很难掌握你的算法......我不明白如何构建对角线不会是 O(nn),与构建特里树...(在最坏的情况下,特里树的解决方案似乎是 O(nn+nn),一次从行 (nn) 构建特里树,另一个用于测试列)
【解决方案2】:

您可以通过计算每行/列的总和并仅在与列总和匹配的行上缩小蛮力比较(最终必须这样做)来加快平均情况。

这不会增加最坏的情况(所有情况都相同),但如果您的输入是真正随机的,那“不会发生”:-)

【讨论】:

  • 是的。我想到了那个。但我没有合并它,因为它不会减少运行时间的限制。有没有一种算法可以在 O(n logn) 或 O(n) 中做到这一点?
  • 似乎因为每一行都必须与你无法绕过的每一列进行比较 (rowcol --> nn)运行时间。话虽如此,他们对排序也说了同样的话,直到 lg-n 排序也出来了......
  • 是的。所以这就是我一直在寻找的。某种 2D 适应快速排序来解决这个问题。
  • @Jasie:O(nlogn) 是堆排序和其他一些最坏情况下的上限。
【解决方案3】:

这可能只适用于非奇异矩阵(不确定),但是...

让 A 是一个正方形(可能是非奇异的)NxN 矩阵。让 A' 是 A 的转置。如果我们创建矩阵 B 使其是 A 和 A' 的水平串联(换句话说 [A A'])并将其放入 RREF 形式,我们将在所有左半边是一个,右半边是一些方阵。

例子:

A = 1 2
    3 4

A'= 1 3
    2 4

B = 1 2 1 3
    3 4 2 4

rref(B) = 1  0 0   -2
          0  1 0.5 2.5

另一方面,如果 A 的一列等于 A 的一行,那么 A 的列将等于 A' 的一列。然后我们会得到另一个 1 in of rref(B) 右半部分的列。

例子

A=
 1     2     3     4     5
 2     6    -3     4     6
 3     8    -7     6     9
 4     1     7    -5     3
 5     2     4    -1    -1

A'=
 1     2     3     4     5
 2     6     8     1     2
 3    -3    -7     7     4
 4     4     6    -5    -1
 5     6     9     3    -1

B = 
 1     2     3     4     5     1     2     3     4     5
 2     6    -3     4     6     2     6     8     1     2
 3     8    -7     6     9     3    -3    -7     7     4
 4     1     7    -5     3     4     4     6    -5    -1
 5     2     4    -1    -1     5     6     9     3    -1

rref(B)=
 1     0     0     0     0    1.000  -3.689  -5.921   3.080   0.495
 0     1     0     0     0        0   6.054   9.394  -3.097  -1.024
 0     0     1     0     0        0   2.378   3.842  -0.961   0.009
 0     0     0     1     0        0  -0.565  -0.842   1.823   0.802
 0     0     0     0     1        0  -2.258  -3.605   0.540   0.662
右半部分 top 行中的

1.000 表示 A 的第一列匹配它的行。 1.000 在右半部分的最左列中,这意味着它是第一行。

【讨论】:

  • 什么是rref,它的复杂性是多少?
【解决方案4】:

不看你的算法或前面答案中的任何方法,但由于矩阵有 n^2 个元素开始,我认为没有比这更好的方法:)

【讨论】:

  • 这个说法不正确。存在具有 n^2 个元素但可以在线性时间内解决的方阵问题。我想说的是,你可以有比输入大小更好的算法。
  • 当然,有些问题您可能不必考虑整个输入(例如“确定 n 个元素序列中的第一个数字”),并且我没有为更低的“参数”声明给定问题的 O(n^2) 界限。我要说的是,对于这个特定问题,很明显您可能必须考虑矩阵中的所有元素!
【解决方案5】:

IFF 矩阵是真正随机的...

您可以创建一个指向按第一个元素排序的列的指针列表。然后创建一个类似的按第一个元素排序的行列表。这需要 O(n*logn)。

接下来为每个初始化为 0 的排序列表创建一个索引。如果第一个元素匹配,则必须比较整行。如果它们不匹配,则增加具有最低起始元素的索引(移动到下一行或下一列)。由于每个索引从 0 到 n-1 仅循环一次,因此您最多可以进行 2*n 次比较,除非所有行和列都以相同的数字开头,但我们说的是随机数矩阵。

在最坏的情况下,行/列比较的时间为 n,但对于随机数据,预计平均为 O(1)。

所以 2 种 O(nlogn),扫描 2*n*1 为您提供 O(nlogn) 的预期运行时间。这当然是假设随机数据。对于大多数元素具有相同值的大型矩阵,最坏的情况仍然是 n**3。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多