【发布时间】:2021-04-21 05:22:39
【问题描述】:
我最近遇到了一个面试问题。
我们有
m*n矩阵,使得每一行都按非递减顺序(按不同元素排序)。按照O(m (log m+ log n))的顺序设计一种算法,以在该矩阵上找到k-th 最小元素(只有一个元素作为k-th 最小元素)。
我认为这是不可能的,所以在 Google 上搜索并找到 this link 和 another solution 和 this answer to a similar question。
我认为如下:
-
将所有行的中值放入一个数组中,我们在
O(m)中找到这个数组的中值并称之为pivot -
我们在
O(m log n)中找到该元素的排名。即:在每一行中有多少元素低于步骤(1)中找到的枢轴。 -
通过比较
k和“枢轴的排名”,我们可以知道每一行中的右半部分或左半部分有效。 (减少到m*n/2矩阵。)
但是这个算法的时间复杂度是O(m * log^2 n)。可以在O(m (log n + log m)) 上运行的算法是什么?有什么想法吗?
【问题讨论】:
-
我认为你建议的算法有一个小问题。矩阵不会减少到
m * n/2,而是每行将被枢轴大致分成两半。所以在第一次迭代之后,行在一般情况下会有不同的大小。 -
@fdermishin 所以你的意思是我提出的算法,对吗?时间复杂度正确吗?
-
算法要求只使用比较操作吗? (例如,基数排序不满足该条件)
-
特殊情况 m==2 是可能的。对于 m==3,这已经非常困难了。
-
@user202729 我们可以使用一个技巧吗?我们知道m个排序数组,整个n个元素,我们知道找到第k个元素有O(m log n)个解决方案,这里我们有m个排序数组(m行)和m * n个元素,所以我们得到O( m (logmn)) 表示 O(m (log (m)+ log (n))
标签: java c++ algorithm math data-structures