LeetCode 378. 有序矩阵中第K小的元素(二分查找)

mac2026-01-28  4

文章目录

1. 题目2. 解题2.1 暴力法2.2 二分查找

1. 题目

给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素。 请注意,它是排序后的第k小元素,而不是第k个元素。

示例: matrix = [ [ 1, 5, 9], [10, 11, 13], [12, 13, 15] ], k = 8, 返回 13。 说明: 你可以假设 k 的值永远是有效的, 1 ≤ k ≤ n^2

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

2.1 暴力法

将所有元素插入小顶堆然后出队k-1个,最后的堆顶就是答案,时间复杂度 O(n2) class Solution { public: int kthSmallest(vector<vector<int>>& matrix, int k) { priority_queue<int,vector<int>,greater<int>> q; for(auto row : matrix) for(auto elem : row) q.push(elem); while(--k) q.pop(); return q.top(); } };

2.2 二分查找

找出矩阵中最小数left,最大数right,第k小的数在left~right之间mid=(left+right) / 2;在矩阵中寻找小于等于mid的元素个数count若count<k,第k小的数在右半部分且不包含mid,即left=mid+1, right=right若count>=k,第k小的数在左半部分且可能包含mid,即left=left, right=mid当left==right时,第k小的数即被找出 class Solution { public: int kthSmallest(vector<vector<int>>& m, int k) { int r = m.size(), c = m[0].size(); int left = m[0][0], right = m[r-1][c-1], mid, count; while(left < right) { mid = left+((right-left)>>1); count = findNotBigerThanMid(m,mid,r,c); if(count < k) left = mid+1; else right = mid; } return left; } int findNotBigerThanMid(vector<vector<int>> &m, int &mid, int &r, int &c) { int i = r-1, j = 0, count = 0; while(i >= 0 && j < c) { //在左下角从下往上找,走台阶状路线,复杂度 O(n) //或者在右上角,一样的道理,跟 if(m[i][j] <= mid) { count += i+1; j++; } else i--; } return count; } };

上面的辅助求count函数,还可写成

int findNotBigerThanMid(vector<vector<int>> &m, int &mid, int &r, int &c) { int i = 0, j = c-1, count = 0; while(i < r && j >= 0) { if(m[i][j] <= mid) { count += j+1; i++; } else j--; } return count; }

参考 Leetcode 240 搜索二维矩阵 II

最新回复(0)