给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素。
请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素。
示例:
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],
k = 8,
返回 13。
提示:
你可以假设 k 的值永远是有效的, 1 ≤ k ≤ n2。
解题思路:优先队列
使用最大堆,当队列中的元素大于k时,便弹出队头元素,由于使用的是最大堆模式,所以最后返回队头元素(即为有序矩阵中第k小的元素)
class Solution {
public:
int kthSmallest(vector<vector<int>>& matrix, int k) {
priority_queue<int> pq;
int rows = matrix.size();
int cols = matrix[0].size();
for(int row = 0;row < rows;row++){
for(int col = 0; col <cols;col++){
pq.push(matrix[row][col]);
if(pq.size() > k){
pq.pop();
}
}
}
return pq.top();
}
};
class Solution:
def kthSmallest(self, matrix: List[List[int]], k: int) -> int:
res = []
rows = len(matrix)
cols = len(matrix[0])
for i in range(rows):
for j in range(cols):
res.append(matrix[i][j])
#sorted是为了解决[[1,2],[1,3]] k=2这个测试案例
return sorted(res)[k-1]
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
说明:
你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。
解题方法:暴力法,直接升序排序之后取倒数第k个值
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
int size = nums.size();
sort(begin(nums), end(nums));
return nums[size - k];
//算法的时间复杂度为 O(NlogN),空间复杂度为 O(1)
}
};
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
#从小到大排序,第k个最大元素即倒数第k个元素
return sorted(nums)[-k]
#算法的时间复杂度为 O(NlogN),空间复杂度为 O(1)
partition(切分)操作,使得:
partition(切分)操作总能排定一个元素,还能够知道这个元素它最终所在的位置,这样每经过一次 partition(切分)操作就能缩小搜索的范围,这样的思想叫做 “减而治之”(是 “分而治之” 思想的特例)。
切分过程可以不借助额外的数组空间,仅通过交换数组元素实现。
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
size = len(nums)
target = size - k
left = 0
right = size - 1
while True:
index = self.partition(nums, left, right)
if index == target:
return nums[index]
elif index < target:
# 下一轮在 [index + 1, right] 里找
left = index + 1
else:
right = index - 1
# 循环不变量:[left + 1, j] < pivot
# (j, i) >= pivot
def partition(self, nums, left, right):
pivot = nums[left]
j = left
for i in range(left + 1, right + 1):
if nums[i] < pivot:
j += 1
nums[i], nums[j] = nums[j], nums[i]
nums[left], nums[j] = nums[j], nums[left]
return j
设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。
示例:
输入: arr = [1,3,5,7,2,4,6,8], k = 4
输出: [1,2,3,4]
提示:
0 <= len(arr) <= 100000
0 <= k <= min(100000, len(arr))
class Solution {
public:
vector<int> smallestK(vector<int>& arr, int k) {
//priority_queue容器,默认从小到大排序,底层实现为最大堆
priority_queue<int> pq;
vector<int> res;
for(auto x : arr){
pq.push(x);
if(pq.size() > k){
pq.pop();
}
}
while(!pq.empty()){
res.push_back(pq.top());
pq.pop();
}
return res;
}
};
class Solution:
def smallestK(self, arr: List[int], k: int) -> List[int]:
return sorted(arr)[:k]