215. Kth Largest Element in an Array
- 数组中的第K个最大元素
感觉是非常经典的一道题目,一开始自己尝试了下手写快排。。一堆bug,又百度学了半天快排算法。。然后试了下评论区大佬的最小堆,这快的也太多了把!完全不是一个数量级的。
感觉手写一个堆结构也是很基本的能力,任重而道远。
1 | class Solution { |
解法2️:最小堆1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53class Solution {
//堆排序的过程就是首先构建大根堆,然后对顶元素(及最大元素)与最后个元素替换位置,heapsize减一,重新调整堆变成大根堆。
//重复上面操作直到heapsize等于一的时候。排序完成。
public int findKthLargest(int[] nums, int k) {
// 建一个大小为k+1(第一个结点不使用)的数组
int[] heap = new int[k+1];
for(int i = 0; i < k; i++){
heap[i+1] = nums[i];
}
// 堆化。建立一个大小为k的小顶堆
// 从最后一个非叶子结点k/2自上往下开始进行堆化,该结点堆化完后就轮到前一个非叶子结点再自上往下进行堆化
for(int i = k/2; i > 0; i--){
heapify(heap,k+1,i);
}
// 继续遍历数组中剩余的数字,并与堆顶元素进行比较,
// 若大于堆顶元素,则替换掉堆顶元素,并自顶向下堆化
for(int i = k; i < nums.length; i++){
if(nums[i] > heap[1]){
heap[1] = nums[i];
heapify(heap,k+1,1);
}
}
return heap[1];
}
// 自顶向下堆化。一般在删除堆顶结点后,把最后一个结点放到堆顶的时候使用。
// 即这时堆中已经是部分堆化
private void heapify(int[] heap,int len,int index){
while(true){
// 找出当前结点和两个直接子结点的最小值
int minPos = index;
if(2*index < len && heap[2*index] < heap[minPos]){
minPos = 2*index;
}
if(2*index+1 < len && heap[2*index+1] < heap[minPos]){
minPos = 2*index + 1;
}
// 若当前结点是最小的,说明下面的是堆化好的了,直接退出循环
if(minPos == index){
break;
}
// 当前结点与最小值进行交换
swap(heap,index,minPos);
// 当前结点更改为最小直接子结点,继续往下堆化
index = minPos;
}
}
private void swap(int[] nums,int i,int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
56. Merge Intervals
56.合并区间
看评论区,基本上都是先按照区间头排序,然后再处理。自己写了个不用sort的算法,用map去替代。有点开心。
1 | class Solution { |
240. Search a 2D Matrix II
- 搜索二维矩阵 II
也就错了这么十几次。。。自闭了。 在分治到2*2范围时我就有点不知道该如何处理了。越写头越晕,无限改BUG。
不过最后效率还是相当不错的。
1 | class Solution { |
感觉时间真的挺紧的,今天上午有点事情就没学习,下午和晚上加起来也就只能刷个三题,书也看不了多少啦。