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

文章目录

    • 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();
    }
};

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

2.2 二分查找

  • 找出矩阵中最小数left,最大数right,第k小的数在left~right之间
  • mid=(left+right) / 2;在矩阵中寻找小于等于mid的元素个数count
  • count,第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
LeetCode 378. 有序矩阵中第K小的元素(二分查找)_第2张图片

你可能感兴趣的:(LeetCode)