【问题标题】:Algorithm with O(m (log n + log m)) time complexity for finding kth smallest element in n*m matrix with each row sorted?具有 O(m (log n + log m)) 时间复杂度的算法,用于在 n*m 矩阵中查找第 k 个最小元素,每行排序?
【发布时间】:2021-04-21 05:22:39
【问题描述】:

我最近遇到了一个面试问题。

我们有m*n 矩阵,使得每一行都按非递减顺序(按不同元素排序)。按照O(m (log m+ log n)) 的顺序设计一种算法,以在该矩阵上找到k-th 最小元素(只有一个元素作为k-th 最小元素)。

我认为这是不可能的,所以在 Google 上搜索并找到 this linkanother solutionthis answer to a similar question

我认为如下:

  1. 将所有行的中值放入一个数组中,我们在O(m)中找到这个数组的中值并称之为pivot

  2. 我们在O(m log n) 中找到该元素的排名。即:在每一行中有多少元素低于步骤(1)中找到的枢轴。

  3. 通过比较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


【解决方案1】:

m - 行 n - 列

  • 您是否需要具有O(m (log m+ log n)) 复杂性的解决方案?

  • 我能想到一个复杂的解决方案O(k * log-m),额外空间为 O(m)

    • 对于这种复杂性,您可以使用修改后的 PriorityQueue(堆)DataStructure
    class PQObject {
        int value; // PQ sorting happens on this int..
        int m; // And m and n are positions.
        int n;
    }
    
  • 您可以将第一列中的所有值放入优先级队列并开始弹出直到第 k 个最小元素

    • 每次弹出时,在弹出的对象中使用 m 和 n 重新插入行的下一个值。
  • 最终问题归结为在 M 个已排序的数组中找到第 k 个最小的元素。

【讨论】:

  • !!这里只对行进行排序,而不是列和行
  • 是的,只是对行进行了排序。所以我为第一列的值创建了一个 PQ。并将跟踪每个元素属于哪一行。我将从 PQ 中弹出,它将返回第一个最小的元素。然后将弹出的下一行元素插入到 PQ 中,并将再次弹出。这就是为什么问题很简单 -> 在 M 个排序的数组中找到第 k 个最小的元素。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-26
  • 1970-01-01
  • 2016-09-02
  • 1970-01-01
  • 1970-01-01
  • 2011-07-09
  • 2012-04-16
相关资源
最近更新 更多