矩阵,算法面试问题

时间:2011-03-23 16:50:35

标签: algorithm matrix rows

这是我的一个面试问题。

我们有一个包含整数的矩阵(没有提供范围)。矩阵随机填充整数。我们需要设计一种算法,该算法可以找到与列完全匹配的行。我们需要返回匹配的行号和列号。匹配元素的顺序是相同的。例如,如果,我的行与第j列匹配,并且我的行包含元素 - [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)。它是否正确?如果正确,是否有更快的算法?

5 个答案:

答案 0 :(得分:4)

您可以从行中的数据构建trie。然后你可以将列与trie进行比较。

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

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

答案 1 :(得分:1)

你可以通过计算每一行/列的总和来加速平均情况,并且只在匹配列总和的行上缩小你的强力比较(你最终必须做的)。

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

答案 2 :(得分:0)

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

设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'的列。然后我们将获得rref(B)的右半部分列中的另一个1。

实施例

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

1.000在右半部分的 top 行中意味着A的第一列与其行匹配。事实上1.000位于右半部分的最左侧列中意味着它是第一行。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

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

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

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

因此2种O(nlogn)和2 * n * 1的扫描给出了预期的运行时间O(nlogn)。这当然是假设随机数据。对于大多数元素具有相同值的大矩阵,最坏情况仍然是n ** 3.