用于求解 **TopK Elements** 问题,通过维护一个大小为 K 的堆,堆中的元素就是 TopK Elements。
用于求解 **TopK Elements** 问题,也就是 K 个最小元素的问题。可以维护一个大小为 K 的最小堆,最小堆中的元素就是最小元素。最小堆需要使用大顶堆来实现,大顶堆表示堆顶元素是堆中最大元素。这是因为我们要得到 k 个最小的元素,因此当遍历到一个新的元素时,需要知道这个新元素是否比堆中最大的元素更小,更小的话就把堆中最大元素去除,并将新元素添加到堆中。所以我们需要很容易得到最大元素并移除最大元素,大顶堆就能很好满足这个要求。
堆排序也可以用于求解 Kth Element 问题,堆顶元素就是 Kth Element。
堆也可以用于求解 Kth Element 问题,得到了大小为 k 的最小堆之后,因为使用了大顶堆来实现,因此堆顶元素就是第 k 大的元素。
快速选择也可以求解 TopK Elements 问题,因为找到 Kth Element 之后,再遍历一次数组,所有小于等于 Kth Element 的元素都是 TopK Elements。
可以看到,快速选择和堆排序都可以求解 Kth Element 和 TopK Elements 问题。
## Kth Element
## 1. Kth Element
[215. Kth Largest Element in an Array (Medium)](https://leetcode.com/problems/kth-largest-element-in-an-array/description/)
题目描述:找到第 k 大的元素。
```text
Input: [3,2,1,5,6,4] and k = 2
Output: 5
```
题目描述:找到倒数第 k 个的元素。
**排序** :时间复杂度 O(NlogN),空间复杂度 O(1)
...
...
@@ -41,7 +46,7 @@ public int findKthLargest(int[] nums, int k) {
}
```
**堆排序** :时间复杂度 O(NlogK),空间复杂度 O(K)。
**堆** :时间复杂度 O(NlogK),空间复杂度 O(K)。
```java
publicintfindKthLargest(int[]nums,intk){
...
...
@@ -97,7 +102,7 @@ private void swap(int[] a, int i, int j) {
# 桶排序
## 出现频率最多的 k 个数
## 1. 出现频率最多的 k 个元素
[347. Top K Frequent Elements (Medium)](https://leetcode.com/problems/top-k-frequent-elements/description/)
...
...
@@ -105,7 +110,7 @@ private void swap(int[] a, int i, int j) {
Given [1,1,1,2,2,3] and k = 2, return [1,2].
```
设置若干个桶,每个桶存储出现频率相同的数,并且桶的下标代表桶中数出现的频率,即第 i 个桶中存储的数出现的频率为 i。
设置若干个桶,每个桶存储出现频率相同的数。桶的下标表示数出现的频率,即第 i 个桶中存储的数出现的频率为 i。
把数都放到桶之后,从后向前遍历桶,最先得到的 k 个数就是出现频率最多的的 k 个数。
...
...
@@ -138,7 +143,7 @@ public List<Integer> topKFrequent(int[] nums, int k) {
}
```
## 按照字符出现次数对字符串排序
## 2. 按照字符出现次数对字符串排序
[451. Sort Characters By Frequency (Medium)](https://leetcode.com/problems/sort-characters-by-frequency/description/)
...
...
@@ -187,14 +192,12 @@ public String frequencySort(String s) {
用于求解 **TopK Elements** 问题,通过维护一个大小为 K 的堆,堆中的元素就是 TopK Elements。
用于求解 **TopK Elements** 问题,也就是 K 个最小元素的问题。可以维护一个大小为 K 的最小堆,最小堆中的元素就是最小元素。最小堆需要使用大顶堆来实现,大顶堆表示堆顶元素是堆中最大元素。这是因为我们要得到 k 个最小的元素,因此当遍历到一个新的元素时,需要知道这个新元素是否比堆中最大的元素更小,更小的话就把堆中最大元素去除,并将新元素添加到堆中。所以我们需要很容易得到最大元素并移除最大元素,大顶堆就能很好满足这个要求。
堆排序也可以用于求解 Kth Element 问题,堆顶元素就是 Kth Element。
堆也可以用于求解 Kth Element 问题,得到了大小为 k 的最小堆之后,因为使用了大顶堆来实现,因此堆顶元素就是第 k 大的元素。
快速选择也可以求解 TopK Elements 问题,因为找到 Kth Element 之后,再遍历一次数组,所有小于等于 Kth Element 的元素都是 TopK Elements。
可以看到,快速选择和堆排序都可以求解 Kth Element 和 TopK Elements 问题。
## Kth Element
## 1. Kth Element
[215. Kth Largest Element in an Array (Medium)](https://leetcode.com/problems/kth-largest-element-in-an-array/description/)
题目描述:找到第 k 大的元素。
```text
Input: [3,2,1,5,6,4] and k = 2
Output: 5
```
题目描述:找到倒数第 k 个的元素。
**排序** :时间复杂度 O(NlogN),空间复杂度 O(1)
...
...
@@ -41,7 +46,7 @@ public int findKthLargest(int[] nums, int k) {
}
```
**堆排序** :时间复杂度 O(NlogK),空间复杂度 O(K)。
**堆** :时间复杂度 O(NlogK),空间复杂度 O(K)。
```java
publicintfindKthLargest(int[]nums,intk){
...
...
@@ -97,7 +102,7 @@ private void swap(int[] a, int i, int j) {
# 桶排序
## 出现频率最多的 k 个数
## 1. 出现频率最多的 k 个元素
[347. Top K Frequent Elements (Medium)](https://leetcode.com/problems/top-k-frequent-elements/description/)
...
...
@@ -105,7 +110,7 @@ private void swap(int[] a, int i, int j) {
Given [1,1,1,2,2,3] and k = 2, return [1,2].
```
设置若干个桶,每个桶存储出现频率相同的数,并且桶的下标代表桶中数出现的频率,即第 i 个桶中存储的数出现的频率为 i。
设置若干个桶,每个桶存储出现频率相同的数。桶的下标表示数出现的频率,即第 i 个桶中存储的数出现的频率为 i。
把数都放到桶之后,从后向前遍历桶,最先得到的 k 个数就是出现频率最多的的 k 个数。
...
...
@@ -138,7 +143,7 @@ public List<Integer> topKFrequent(int[] nums, int k) {
}
```
## 按照字符出现次数对字符串排序
## 2. 按照字符出现次数对字符串排序
[451. Sort Characters By Frequency (Medium)](https://leetcode.com/problems/sort-characters-by-frequency/description/)
...
...
@@ -187,14 +192,12 @@ public String frequencySort(String s) {