有序矩阵中第K小的元素
题目描述
给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素。
请注意,它是排序后的第k小元素,而不是第k个元素。
示例:
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],
k = 8,
返回 13。
解题思路
个人AC
无。
最优解
二分查找
- 声明两个变量
minInR和maxInR来标识指定矩阵的最小值和最大值,且minInR一定是左上角元素,maxInR一定是右下角元素; - 初始化
minInR为矩阵左上角元素minInR = matrix[0][0],maxInR为矩阵右下角元素maxInR = matrix[n - 1][n - 1],则第k小的元素一定在minInR和maxInR之间; - 不断收缩
minInR和maxInR的范围,直到minInR == maxInR,以找出目标元素:- 声明变量
mid标识minInR和maxInR的平均值; - 在指定矩阵中寻找小于等于
mid的元素个数count; - 如果
count < k,表明第k小的元素在右半部分且不包括mid,即minInR = mid + 1, maxInR = maxInR; - 否则
count >= k,表明第k小的元素在左半部分可能包括mid,即minInR = minInR, maxInR = mid。
- 声明变量
class Solution {
public int kthSmallest(int[][] matrix, int k) {
int n = matrix.length;
int minInR = matrix[0][0], maxInR = matrix[n - 1][n - 1];
while (minInR < maxInR) {
int mid = (maxInR + minInR) / 2;
int count = countNotBiggerThan(matrix, mid);
if (count < k) {
// 第k小的元素在右半部分,且不包含mid
minInR = mid + 1;
} else {
// 第k小的元素在左半部分,可能包含mid
maxInR = mid;
}
}
return maxInR;
}
private int countNotBiggerThan(int[][] matrix, int mid) {
int n = matrix.length;
int count = 0;
int i = n - 1, j = 0; // 以列为单位,从矩阵左下角开始
while (i >= 0 && j < n) {
if (matrix[i][j] <= mid) {
count += i + 1; // matrix[i][j]及其所在列上方元素也都小于等于mid
j++;
} else {
i--; // 在同一列中往上走
}
}
return count;
}
}

本文介绍了一种在有序矩阵中查找第K小元素的高效算法。通过使用二分查找策略,确定目标元素位于矩阵最小值和最大值之间。算法不断调整搜索范围,直至找到确切的元素位置。
818

被折叠的 条评论
为什么被折叠?



