给定一个m行和n列的矩阵,每个矩阵都有排序。如何有效地对整个矩阵进行排序?
我知道一个以O(m n log(min(m,n))运行的解决方案。我正在寻找更好的解决方案。
我知道的方法一次只需要2行/列并应用合并操作。
以下是一个例子:
[[1,4,7,10],
[2,5,8,11],
[3,6,9,12]]
是输入martix,其中每行和每列都已排序。
预期输出为:
[1,2,3,4,5,6,7,8,9,10,11,12]
另一个例子:
[[1, 2, 3, 3, 4, 5, 6, 6, 7, 7],
[1, 2, 4, 6, 7, 7, 8, 8, 9,10],
[3, 3, 4, 8, 8, 9,10,11,11,12],
[3, 3, 5, 8, 8, 9,12,12,13,14]]
答案 0 :(得分:46)
我认为你不能比Ω( mn log(min( m , n ))更快地完成它,至少在一般情况下不是。
假设(不失一般性) m < 名词的。然后你的矩阵看起来像这样:
每个圆圈都是一个矩阵条目,每个箭头表示一个已知的顺序关系(箭头来源的条目小于箭头目的地的条目)。
要对矩阵进行排序,我们必须解决所有未知的顺序关系,其中一些显示在灰色框中:
对所有这些框进行排序需要:
2Σ k < m Ω( k log k )+( n - m + 1)Ω( m log m )
=2Ω( m ²log m )+( n - m + 1)Ω( m log m )
=Ω( m n log m )
答案 1 :(得分:0)
如果元素是某个范围内的整数k,其中K = o(mn),我们可以使用带有额外空间的count排序来实现O(mn),否则mnlog(min(m,n))是最好的我们能做到。
答案 2 :(得分:0)
通过创建二进制搜索树,我们可以在O(mn)时间内完成此操作。 从第一列中获取最后一个元素(上面提到的示例中的元素3),将其作为根。右边节点将是最后一行的n个更大元素,左边节点将是元素上面的元素,即。第(m-1)个或第二个最后一行的第一个元素。类似地,对于该元素,右节点将是该行的n个元素。同样,m-2将是左侧元素,并且其行中的所有n个元素将是正确的元素。同样向前推进我们将在O(mn)时间内创建一个二叉搜索树。这是O(mn),因为我们在插入时没有搜索,它是一个简单的插入,同时通过移动根节点指针进行遍历。 然后按顺序遍历此BST,这也将是O(mn)时间。