快排:
挖坑填数 + 分治
复杂度:最快O(nlog(n)),最慢O(n^2)
void quick_sort(vector<int> &nums, int left, int right)
{
if(left < right)
{
int i = left, j = right, key = nums[left];
while(i < j)
{
while(i < j && nums[j] >= key)
j--;
nums[i] = nums[j];
while(i < j && nums[i] <= key)
i++;
nums[j] = nums[i];
}
nums[i] = key;
quick_sort(nums, left, i - 1);
quick_sort(nums, i + 1, right);
}
}
归并排序:
分为排好序的两部分 + 合并
void merge_sort(vector<int> &nums, int l, int r, vector<int> &temp)
{
if(l < r)
{
int mid = (l + r) >> 1;
merge_sort(nums, l, mid, temp);
merge_sort(nums, mid + 1, r, temp);
int i = l, j = mid + 1, t = l;
while(i < mid + 1 && j < r + 1)
{
if(nums[i] < nums[j])
temp[t++] = nums[i++];
else
temp[t++] = nums[j++];
}
while(i < mid + 1)
{
temp[t++] = nums[i++];
}
while(j < r + 1)
{
temp[t++] = nums[j++];
}
t = l;
while(t < r + 1)
{
nums[t] = temp[t];
t++;
}
}
}
堆排序:堆排序讲解
void max_heapify(vector<int> &nums, int start, int end) //大顶堆调整
{
int dad = start;
int son = dad * 2 + 1;
while(son <= end)
{
if(son + 1 <= end && nums[son] < nums[son + 1]) //比较两个子节点谁更大
son++;
if(nums[dad] >= nums[son])
return;
else //交换完后,需要进一步判断交换后的孩子树是否满足大顶堆条件
{
swap(nums[dad], nums[son]);
dad = son;
son = dad * 2 + 1;
}
}
}
void heap_sort(vector<int> &nums, int len)
{
for (int i = len / 2 - 1; i >= 0; i--) //对于无序数组,先对每个父节点进行大顶堆调整
max_heapify(nums, i, len - 1);
for (int i = len - 1; i > 0;i--)
{
swap(nums[i], nums[0]); //交换第一个与最后一个值
max_heapify(nums, 0, i - 1); //对无序的根节点nums[0]在i - 1范围内进行大顶堆调整
}
}
215.数组中的第k个最大元素
题解:可以采用快速选择即快速排序的子过程,寻找大于某个元素的数的个数等于k。可以采用二分法进行逐步判断。也可以采用大顶堆排序,寻找第k个大的元素。
//二分 + 快速选择
class Solution {
public:
int quick_select(vector<int> &nums, int left, int right)
{
int i = left, j = right, key = nums[i];
while(i < j)
{
while(i < j && nums[j] >= key)
j--;
nums[i] = nums[j];
while(i < j && nums[i] <= key)
i++;
nums[j] = nums[i];
}
nums[i] = key;
return i;
}
int findKthLargest(vector<int>& nums, int k) {
if(nums.size() == 1)
{
return nums[0];
}
int l = 0, r = nums.size() - 1;
int n;
while(l < r)
{
n = quick_select(nums, l, r);
if(nums.size() - n == k)
return nums[n];
else if (nums.size() - n < k)
r = n - 1;
else
l = n + 1;
}
return nums[r];
}
};
//大顶堆排序
class Solution {
public:
void max_heapify(vector<int> &nums, int start, int end)
{
int dad = start;
int son = dad * 2 + 1;
while(son <= end)
{
if(son + 1 <= end && nums[son] < nums[son + 1])
son++;
if(nums[dad] > nums[son])
return;
else
{
swap(nums[dad], nums[son]);
dad = son;
son = dad * 2 + 1;
}
}
}
int findKthLargest(vector<int>& nums, int k) {
int len = nums.size();
for(int i = len / 2 - 1; i >= 0 ; i--)
max_heapify(nums, i, len - 1);
int numb = 0;
for(int i = len - 1;i >= 0; i--)
{
swap(nums[i], nums[0]);
numb++;
if(numb == k)
return nums[i];
max_heapify(nums, 0, i - 1);
}
return 0; //无用
}
};
347.前k个高频元素
题解:可以采用优先队列,对元素出现的个数进行排序,从得到最终结果。也可以采用桶排序将出现次数作为二维数组的下标,即可统计得到以下标为出现次数,值为元素的二维数组,然后按条件输出结果即可。
//优先队列
class Solution {
public:
class mycompare
{
public:
bool operator()(const pair<int, int> &a, const pair<int, int> &b)
{
return a.second > b.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> m;
for(int i = 0;i<nums.size(); i++)
++m[nums[i]];
priority_queue<pair<int, int>, vector<pair<int, int>>, mycompare> pq;
for(auto const &p: m)
{
pq.push(p);
if(pq.size() > k)
{
pq.pop();
}
}
vector<int> res;
for(int i = 0;i<k;i++)
{
res.push_back(pq.top().first);
pq.pop();
}
return res;
}
};
//桶排序
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> m;
int max_count = 0;
for(int i = 0;i<nums.size();i++)
max_count = std::max(max_count, ++m[nums[i]]);
vector<vector<int>> v(max_count + 1);
for(auto const &p: m)
{
v[p.second].push_back(p.first);
}
vector<int> res;
for(int i = max_count; i>= 0 && res.size() < k;i--)
{
for(auto const &p : v[i])
{
res.push_back(p);
if(res.size() == k)
break;
}
}
return res;
}
};
75.颜色分类
题解:采用双指针p0 p2,遍历数组,nums[i] 若等于0则将nums[p0]与nums[i]交换,若等于2则将nums[i]与nums[p2]交换,在交换2时会出现将两个都为2的值进行交换的情况,因此需要循环交换,直到p2指向非2值或等于i
class Solution {
public:
void sortColors(vector<int>& nums) {
int p0 = 0, p2 = nums.size() - 1;
for(int i = 0;i<nums.size();i++)
{
while(i < p2 && nums[i] == 2)
{
swap(nums[i], nums[p2]);
p2--;
}
if(nums[i] == 0)
{
swap(nums[i], nums[p0]);
p0++;
}
}
}
};