Skip to content

Commit f1158ac

Browse files
Merge pull request #708 from SharingSource/ac_oier
✨feat: add 215 & 801
2 parents 5cce3ae + 724099b commit f1158ac

File tree

8 files changed

+390
-6
lines changed

8 files changed

+390
-6
lines changed

Index/二分.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
| [154. 寻找旋转排序数组中的最小值 II](https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/solution/gong-shui-san-xie-xiang-jie-wei-he-yuan-7xbty/) | 困难 | 🤩🤩🤩 |
1212
| [162. 寻找峰值](https://leetcode-cn.com/problems/find-peak-element/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-peak-element/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-qva7v/) | 中等 | 🤩🤩🤩🤩🤩 |
1313
| [209. 长度最小的子数组](https://leetcode.cn/problems/minimum-size-subarray-sum/) | [LeetCode 题解链接](https://leetcode.cn/problems/minimum-size-subarray-sum/solution/by-ac_oier-c5jm/) | 中等 | 🤩🤩🤩🤩🤩 |
14+
| [215. 数组中的第K个最大元素](https://leetcode.cn/problems/kth-largest-element-in-an-array/) | [LeetCode 题解链接](https://leetcode.cn/problems/kth-largest-element-in-an-array/solution/by-ac_oier-x9h4/) | 中等 | 🤩🤩🤩 |
1415
| [220. 存在重复元素 III](https://leetcode-cn.com/problems/contains-duplicate-iii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/contains-duplicate-iii/solution/gong-shui-san-xie-yi-ti-shuang-jie-hua-d-dlnv/) | 中等 | 🤩🤩🤩 |
1516
| [240. 搜索二维矩阵 II](https://leetcode-cn.com/problems/search-a-2d-matrix-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/search-a-2d-matrix-ii/solution/gong-shui-san-xie-yi-ti-shuang-jie-er-fe-y1ns/) | 中等 | 🤩🤩🤩🤩🤩 |
1617
| [274. H 指数](https://leetcode-cn.com/problems/h-index/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/h-index/solution/gong-shui-san-xie-li-yong-er-duan-xing-z-1jxw/) | 中等 | 🤩🤩🤩 |

Index/堆.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
| 题目 | 题解 | 难度 | 推荐指数 |
22
| ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -------- |
33
| [23. 合并K个升序链表](https://leetcode-cn.com/problems/merge-k-sorted-lists/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/merge-k-sorted-lists/solution/shua-chuan-lc-you-xian-dui-lie-jie-fa-sh-3flb/) | 困难 | 🤩🤩🤩 |
4+
| [215. 数组中的第K个最大元素](https://leetcode.cn/problems/kth-largest-element-in-an-array/) | [LeetCode 题解链接](https://leetcode.cn/problems/kth-largest-element-in-an-array/solution/by-ac_oier-x9h4/) | 中等 | 🤩🤩🤩 |
45
| [218. 天际线问题](https://leetcode-cn.com/problems/the-skyline-problem/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/the-skyline-problem/solution/gong-shui-san-xie-sao-miao-xian-suan-fa-0z6xc/) | 困难 | 🤩🤩🤩 |
56
| [239. 滑动窗口最大值](https://leetcode.cn/problems/sliding-window-maximum/) | [LeetCode 题解链接](https://leetcode.cn/problems/sliding-window-maximum/solution/by-ac_oier-o89l/) | 困难 | 🤩🤩🤩🤩🤩 |
67
| [264. 丑数 II](https://leetcode-cn.com/problems/ugly-number-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/ugly-number-ii/solution/gong-shui-san-xie-yi-ti-shuang-jie-you-x-3nvs/) | 中等 | 🤩🤩🤩 |

Index/排序.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
| ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -------- |
33
| [41. 缺失的第一个正数](https://leetcode-cn.com/problems/first-missing-positive/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/first-missing-positive/solution/yan-ge-on-de-tong-pai-xu-si-lu-yi-ji-wei-wm8d/) | 困难 | 🤩🤩🤩 |
44
| [75. 颜色分类](https://leetcode.cn/problems/sort-colors/) | [LeetCode 题解链接](https://leetcode.cn/problems/sort-colors/solution/by-ac_oier-7lwk/) | 中等 | 🤩🤩🤩🤩🤩 |
5+
| [215. 数组中的第K个最大元素](https://leetcode.cn/problems/kth-largest-element-in-an-array/) | [LeetCode 题解链接](https://leetcode.cn/problems/kth-largest-element-in-an-array/solution/by-ac_oier-x9h4/) | 中等 | 🤩🤩🤩🤩🤩 |
56
| [220. 存在重复元素 III](https://leetcode-cn.com/problems/contains-duplicate-iii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/contains-duplicate-iii/solution/gong-shui-san-xie-yi-ti-shuang-jie-hua-d-dlnv/) | 中等 | 🤩🤩🤩 |
67
| [268. 丢失的数字](https://leetcode-cn.com/problems/missing-number/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/missing-number/solution/gong-shui-san-xie-yi-ti-wu-jie-pai-xu-ji-te3s/) | 简单 | 🤩🤩🤩🤩 |
78
| [324. 摆动排序 II](https://leetcode.cn/problems/wiggle-sort-ii/) | [LeetCode 题解链接](https://leetcode.cn/problems/wiggle-sort-ii/solution/by-ac_oier-22bq/) | 中等 | 🤩🤩🤩🤩 |

Index/树状数组.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
| 题目 | 题解 | 难度 | 推荐指数 |
22
| ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -------- |
3+
| [215. 数组中的第K个最大元素](https://leetcode.cn/problems/kth-largest-element-in-an-array/) | [LeetCode 题解链接](https://leetcode.cn/problems/kth-largest-element-in-an-array/solution/by-ac_oier-x9h4/) | 中等 | 🤩🤩🤩 |
34
| [307. 区域和检索 - 数组可修改](https://leetcode-cn.com/problems/range-sum-query-mutable/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/range-sum-query-mutable/solution/guan-yu-ge-lei-qu-jian-he-wen-ti-ru-he-x-41hv/) | 中等 | 🤩🤩🤩🤩🤩 |
45
| [327. 区间和的个数](https://leetcode.cn/problems/count-of-range-sum/) | [LeetCode 题解链接](https://leetcode.cn/problems/count-of-range-sum/solution/by-ac_oier-b36o/) | 困难 | 🤩🤩🤩🤩🤩 |
56
| [406. 根据身高重建队列](https://leetcode.cn/problems/queue-reconstruction-by-height/) | [LeetCode 题解链接](https://leetcode.cn/problems/queue-reconstruction-by-height/solution/by-ac_oier-fda2/) | 中等 | 🤩🤩🤩 |

Index/状态机 DP.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
| 题目 | 题解 | 难度 | 推荐指数 |
22
| ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -------- |
33
| [552. 学生出勤记录 II](https://leetcode-cn.com/problems/student-attendance-record-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/student-attendance-record-ii/solution/gong-shui-san-xie-yi-ti-san-jie-ji-yi-hu-fdfx/) | 困难 | 🤩🤩🤩🤩 |
4+
| [801. 使序列递增的最小交换次数](https://leetcode.cn/problems/minimum-swaps-to-make-sequences-increasing/) | [LeetCode 题解链接](https://leetcode.cn/problems/minimum-swaps-to-make-sequences-increasing/solution/by-ac_oier-fjhp/) | 困难 | 🤩🤩🤩🤩🤩 |
45
| [1218. 最长定差子序列](https://leetcode-cn.com/problems/longest-arithmetic-subsequence-of-given-difference/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-arithmetic-subsequence-of-given-difference/solution/gong-shui-san-xie-jie-he-tan-xin-de-zhua-dj1k/) | 中等 | 🤩🤩🤩🤩🤩 |
56
| [剑指 Offer II 091. 粉刷房子](https://leetcode.cn/problems/JEj789/) | [LeetCode 题解链接](https://leetcode.cn/problems/JEj789/solution/by-ac_oier-6v2v/) | 中等 | 🤩🤩🤩🤩🤩 |
67

LeetCode/11-20/19. 删除链表的倒数第 N 个结点(中等).md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,13 @@ Tag : 「链表」、「快慢指针」、「双指针」
5858
class Solution {
5959
public ListNode removeNthFromEnd(ListNode head, int n) {
6060
if (head.next == null) return null;
61-
62-
ListNode slow = head;
63-
ListNode fast = head;
61+
ListNode slow = head, fast = head;
6462
while (n-- > 0) fast = fast.next;
65-
6663
if (fast == null) {
6764
head = slow.next;
6865
} else {
6966
while (fast.next != null) {
70-
slow = slow.next;
71-
fast = fast.next;
67+
slow = slow.next; fast = fast.next;
7268
}
7369
slow.next = slow.next.next;
7470
}
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[215. 数组中的第K个最大元素](https://leetcode.cn/problems/kth-largest-element-in-an-array/solution/by-ac_oier-x9h4/)** ,难度为 **中等**
4+
5+
Tag : 「树状数组」、「二分」、「优先队列(堆)」、「快速选择」
6+
7+
8+
9+
给定整数数组 `nums` 和整数 `k`,请返回数组中第 `k` 个最大的元素。
10+
11+
请注意,你需要找的是数组排序后的第 `k` 个最大的元素,而不是第 `k` 个不同的元素。
12+
13+
你必须设计并实现时间复杂度为 $O(n)$ 的算法解决此问题。
14+
15+
示例 1:
16+
```
17+
输入: [3,2,1,5,6,4], k = 2
18+
19+
输出: 5
20+
```
21+
示例 2:
22+
```
23+
输入: [3,2,3,1,2,4,5,5,6], k = 4
24+
25+
输出: 4
26+
```
27+
28+
提示:
29+
* $1 <= k <= nums.length <= 10^5$
30+
* $-10^4 <= nums[i] <= 10^4$
31+
32+
---
33+
34+
### 值域映射 + 树状数组 + 二分
35+
36+
除了直接对数组进行排序,取第 $k$ 位的 $O(n\log{n})$ 做法以外。
37+
38+
对于值域大小 小于 数组长度本身时,我们还能使用「树状数组 + 二分」的 $O(n\log{m})$ 做法,其中 $m$ 为值域大小。
39+
40+
首先值域大小为 $[-10^4, 10^4]$,为了方便,我们为每个 $nums[i]$ 增加大小为 $1e4 + 10$ 的偏移量,将值域映射到 $[10, 2 \times 10^4 + 10]$ 的空间。
41+
42+
将每个增加偏移量后的 $nums[i]$ 存入树状数组,考虑在 $[0, m)$ 范围内进行二分,假设我们真实第 $k$ 大的值为 $t$,那么在以 $t$ 为分割点的数轴上,具有二段性质:
43+
44+
* 在 $[0, t]$ 范围内的数 $cur$ 满足「树状数组中大于等于 $cur$ 的数不低于 $k$ 个」
45+
* 在 $(t, m)$ 范围内的数 $cur$ 不满足「树状数组中大于等于 $cur$ 的数不低于 $k$ 个」
46+
47+
二分出结果后再减去刚开始添加的偏移量即是答案。
48+
49+
代码:
50+
```Java
51+
class Solution {
52+
int M = 10010, N = 2 * M;
53+
int[] tr = new int[N];
54+
int lowbit(int x) {
55+
return x & -x;
56+
}
57+
int query(int x) {
58+
int ans = 0;
59+
for (int i = x; i > 0; i -= lowbit(i)) ans += tr[i];
60+
return ans;
61+
}
62+
void add(int x) {
63+
for (int i = x; i < N; i += lowbit(i)) tr[i]++;
64+
}
65+
public int findKthLargest(int[] nums, int k) {
66+
for (int x : nums) add(x + M);
67+
int l = 0, r = N - 1;
68+
while (l < r) {
69+
int mid = l + r + 1 >> 1;
70+
if (query(N - 1) - query(mid - 1) >= k) l = mid;
71+
else r = mid - 1;
72+
}
73+
return r - M;
74+
}
75+
}
76+
```
77+
* 时间复杂度:将所有数字放入树状数组复杂度为 $O(n\log{m})$;二分出答案复杂度为 $O(\log^2{m})$,其中 $m = 2 \times 10^4$ 为值域大小。整体复杂度为 $O(n\log{m})$
78+
* 空间复杂度:$O(m)$
79+
80+
---
81+
82+
### 优先队列(堆)
83+
84+
另外一个容易想到的想法是利用优先队列(堆),由于题目要我们求的是第 $k$ 大的元素,因此我们建立一个小根堆。
85+
86+
根据当前队列元素个数或当前元素与栈顶元素的大小关系进行分情况讨论:
87+
88+
* 当优先队列元素不足 $k$ 个,可将当前元素直接放入队列中;
89+
* 当优先队列元素达到 $k$ 个,并且当前元素大于栈顶元素(栈顶元素必然不是答案),可将当前元素放入队列中。
90+
91+
代码:
92+
```Java
93+
class Solution {
94+
public int findKthLargest(int[] nums, int k) {
95+
PriorityQueue<Integer> q = new PriorityQueue<>((a,b)->a-b);
96+
for (int x : nums) {
97+
if (q.size() < k || q.peek() < x) q.add(x);
98+
if (q.size() > k) q.poll();
99+
}
100+
return q.peek();
101+
}
102+
}
103+
```
104+
* 时间复杂度:$O(n\log{k})$
105+
* 空间复杂度:$O(k)$
106+
107+
---
108+
109+
### 快速选择
110+
111+
对于给定数组,求解第 $k$ 大元素,且要求线性复杂度,正解为使用「快速选择」做法。
112+
113+
基本思路与「快速排序」一致,每次敲定一个基准值 `x`,根据当前与 `x` 的大小关系,将范围在 $[l, r]$ 的 $nums[i]$ 划分为到两边。
114+
115+
同时利用,利用题目只要求输出第 $k$ 大的值,而不需要对数组进行整体排序,我们只需要根据划分两边后,第 $k$ 大数会落在哪一边,来决定对哪边进行递归处理即可。
116+
117+
> 快速排序模板为面试向重点内容,需要重要掌握。
118+
119+
代码:
120+
```Java
121+
class Solution {
122+
int[] nums;
123+
int qselect(int l, int r, int k) {
124+
if (l == r) return nums[k];
125+
int x = nums[l], i = l - 1, j = r + 1;
126+
while (i < j) {
127+
do i++; while (nums[i] < x);
128+
do j--; while (nums[j] > x);
129+
if (i < j) swap(i, j);
130+
}
131+
if (k <= j) return qselect(l, j, k);
132+
else return qselect(j + 1, r, k);
133+
}
134+
void swap(int i, int j) {
135+
int c = nums[i];
136+
nums[i] = nums[j];
137+
nums[j] = c;
138+
}
139+
public int findKthLargest(int[] _nums, int k) {
140+
nums = _nums;
141+
int n = nums.length;
142+
return qselect(0, n - 1, n - k);
143+
}
144+
}
145+
```
146+
* 时间复杂度:期望 $O(n)$
147+
* 空间复杂度:忽略递归带来的额外空间开销,复杂度为 $O(1)$
148+
149+
---
150+
151+
### 最后
152+
153+
这是我们「刷穿 LeetCode」系列文章的第 `No.215` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
154+
155+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
156+
157+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
158+
159+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
160+

0 commit comments

Comments
 (0)