快速排序
🚀快速排序相当于二叉树的前序遍历
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
// 快速排序相当于二叉树的前序遍历
if(nums.size() <= 1) return nums;
quick_sort(nums, 0, nums.size() - 1);
return nums;
}
void quick_sort(vector<int>& nums, int left, int right){
// 终止条件
if(left >= right) return;
// 单层排序的逻辑
int mid = nums[left + right >> 1], i = left - 1, j = right + 1;
while(i < j){
while(nums[++i] < mid);
while(nums[--j] > mid);
if(i < j) swap(nums[i], nums[j]);
}
// 递归地排左边, 排右边
quick_sort(nums, left, j); quick_sort(nums, j+1, right);
}
};
第k大的数
🚀快速选择算法:快速排序(从大到小排序) + 判断第k个数在左边还是右边,这样只需递归其中一边即可。需要注意的是在左边找第k
个数,在右边则是找k - sl(左边元素的个数)
个数。
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
// 快速选择算法
return quick_sort(nums, 0, nums.size() - 1, k);
}
int quick_sort(vector<int>& nums, int left, int right, int k){
if(left >= right) return nums[left];
int mid = nums[left + right >> 1], i = left - 1, j = right + 1;
while(i < j){
while(nums[++i] > mid);
while(nums[--j] < mid);
if(i < j) swap(nums[i], nums[j]);
}
// 统计左边的个数
int sl = j - left + 1;
// 判断第k个数在左边还是右边,只需递归其中一边即可
if(sl >= k) return quick_sort(nums, left, j, k);
else return quick_sort(nums, j + 1, right, k - sl);
}
};
两数之和
🚀哈希表:将遍历过的数组元素和索引加入到哈希表中,每次查找哈希表中是否存在target - nums[i]
的元素
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
// 初始化一个哈希表
unordered_map<int, int> map;
for(int i = 0; i < nums.size(); i++){
auto it = map.find(target - nums[i]);
// 如果找到则直接返回结果集
if(it != map.end()) return {i, it->second};
// 如果没有找到则把当前的数和索引加入到哈希表中
else map.insert({nums[i], i});
}
return {};
}
};
三数之和
🚀排序+双指针+去重
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
//排序
sort(nums.begin(), nums.end());
//初始化结果集
vector<vector<int>> result;
// 遍历数组
for(int i = 0; i < nums.size(); i++){
// 如果nums[i] > 0,说明后面的数全部>0,直接返回结果集
if(nums[i] > 0) return result;
// 去重, 当num[i] == num[i - 1]时,会出现重复的结果集
if(i > 0 && nums[i] == nums[i - 1]) continue;
// 双指针
int left = i + 1, right = nums.size() - 1;
while(left < right){
if(nums[i] + nums[left] + nums[right] > 0) right--;
else if(nums[i] + nums[left] + nums[right] < 0) left++;
else{
//收获结果
result.push_back({nums[i], nums[left], nums[right]});
// 去重,当num[left] == num[left + 1]或者num[right] == num[right - 1]时
while(left < right && nums[left] == nums[left + 1]) left++;
while(left < right && nums[right] == nums[right - 1]) right--;
left++; right--;
}
}
}
return result;
}
};
滑动窗口最大值
🚀单调队列经典问题
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
deque<int> q;
vector<int> res;
for(int i = 0; i < nums.size(); i++){
while(q.size() && q.front() <= i - k) q.pop_front();
while(q.size() && nums[q.back()] <= nums[i]) q.pop_back();
q.push_back(i);
if(i >= k - 1) res.push_back(nums[q.front()]);
}
return res;
}
};