题目:
给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。
请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素。
示例:
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],
k = 8,返回 13。
提示:
- 你可以假设 k 的值永远是有效的,1 ≤ k ≤ n2 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix
方法一:
n个有序队列进行归并,找到第k个数。
class Solution:
def kthSmallest(self, matrix: List[List[int]], k: int) -> int:
n = len(matrix)
T = [0]*n
result = []
while(len(result)!=k):
x = -1
min_val = float('inf')
for i in range(n):
if T[i]<n:
if matrix[i][T[i]]<min_val:
x = i
min_val = matrix[i][T[i]]
T[x]+=1
result.append(min_val)
return result[-1]
方法二:
二分法,已知最大值r和最小值l,利用矩阵的性质可以快速计算小于中值mid(l<=mid<=r)(从左下角开始遍历,计数每列小于mid的值),
通过不断二分,找到合适的mid值。
class Solution:
def kthSmallest(self, matrix: List[List[int]], k: int) -> int:
n = len(matrix)
if k==1:
return matrix[0][0]
elif k==n**n:
return matrix[n-1][n-1]
l = matrix[0][0]
r = matrix[n-1][n-1]
while(1):
mid = (l+r)//2
T = 0
i = n-1
j = 0
count = 0
while(i>=0 and j<n):
if matrix[i][j]<mid:
count+= (i+1)
j+=1
elif matrix[i][j]==mid: #右移
count+= i
j+=1
T += 1
else:
i-=1 #上移
if count+T>=k and count<k and T>0:
return mid
elif count<k:
if mid!=l:
l = mid
else:
l = l+1
else:
if mid!=r:
r = mid
else:
r = r-1