📸排序📸
📸排序📸
堆排序、快速排序
建立哈希表并排序
荷兰国旗问题
数组中的第K个最大元素
leetcode在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
使用SLT库排序
1 |
|
堆排序解题思路
- 堆排序会使用到优先队列
priority_queue
,可以当成一种高级队列,只不过这个队列是已经排好序的。 - 维护一个个数为k的小顶堆,堆从从上到下按从小到大排序
- 始终保持堆的大小为k,超出k就pop(),直到遍历结束位置,堆中存放着前k个最大元素,堆顶的元素就是正确答案。
1
2
3
4
5
6
7
8int findKthLargest(vector<int>& nums, int k) {
priority_queue<int, vector<int>, greater<int> > queue;
for (auto it : nums) {
queue.push(it);
if (queue.size() > k) queue.pop();
}
return queue.top();
}快速排序解题思路
- 不使用STL库的情况下,手写一个快速排序算法
- 注意:快速排序使用的是递归,所以记得一定要写个递归结束条件
if (left > right) return ;。
- 注意:在partition函数中while里处理要判断nums[right] >= p,还要判断left < right。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23int findKthLargest(vector<int>& nums, int k) {
quickSort(nums, 0, nums.size() - 1);
return nums[nums.size() - k];
}
void quickSort(vector<int>& nums, int left, int right) {
if (left > right) return ;
int mid = partition(nums, left, right);
quickSort(nums, left, mid - 1);
quickSort(nums, mid + 1,right);
}
int partition(vector<int>& nums, int left, int right) {
int p = nums[left];
while (left < right) {
while (nums[right] >= p && left < right) right--;
nums[left] = nums[right];
while (nums[left] <= p && left < right) left++;
nums[right] = nums[left];
}
nums[left] = p;
return left;
}
前K个高频元素
leetcode给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例
1 |
|
解题思路
- 建立哈希表统计数字出现频率,
- 利用隐式转换,把无序hash转换为pair类型方便按照频率多少进行排序
- 使用SLT的sort()函数进行排序,大小的比较规则cmp函数需要自己写。
- 将排好序的前k元素输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16static bool cmp(pair<int, int> v1, pair<int, int> v2){
return v1.second > v2.second;
}
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int> hash;
for (int i = 0; i < nums.size(); ++i) {
hash[nums[i]]++;
}
vector<pair<int, int> > arr(hash.begin(), hash.end());
sort(arr.begin(), arr.end(), cmp);
vector<int> res;
for(int i = 0; i < k; ++i){
res.push_back(arr[i].first);
}
return res;
}
按照字符出现次数对字符串排序
leetcode给定一个字符串,请将字符串里的字符按照出现的频率降序排列。
解题思路
- 哈希表建立的频率表是无序的,所以需要转换为其他数据结构,再使用排序算法对其排序
- 可以使用隐式的类型转换为
pair<char,int>
,再使用STL里面的sort()函数进行排序,sort的好处是可以自定义排序的规则。 - sort()函数自定义的排序规则需要写成静态的函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18static bool cmp(pair<char, int> a, pair<char, int> b) {
return a.second > b.second;
}
string frequencySort(string s) {
unordered_map<char, int>hash;
for (auto it : s) {
hash[it]++;
}
vector<pair<char, int> > arr(hash.begin(), hash.end());
sort(arr.begin(), arr.end(), cmp);
string res;
for (auto it : arr) {
while (it.second--) {
res.push_back(it.first);
}
}
return res;
}
荷兰国旗
Leetcode给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
解题思路
- 一共三个指针,p0一直指向0的后一位,p2一直指向2的前一位,cur是用于遍历的指针。
- 本题属于荷兰旗帜问题:思想是遇到0就跟p0所指的数交换位置,遇到2就跟p2所指的数交换位置,遇到1就跳过。
- 注意:遇到2交换完位置后,cur指针不前进,因为要再次判断交换过来的数是0还是1。
- 注意2:while结束是
cur < p2
而不是cur < nums.size()
1
2
3
4
5
6
7
8
9void sortColors(vector<int>& nums) {
int p0 = 0, p2 = nums.size() - 1;
int cur = 0;
while (cur < p2) {
if (nums[cur] == 1) cur++;
else if (nums[cur] == 0) swap(nums[p0++], nums[cur++]);
else if (nums[cur] == 2) swap(nums[cur],nums[p2--]);
}
}