【排序算法】堆排、快排、归并排、各种排
1、堆
2、快排
颜色分类
- 颜色分类
class Solution {
public:
void sortColors(vector<int>& nums) {
int i = 0, l = -1, r = nums.size();
while (i < r)
{
if (nums[i] == 0) swap(nums[++l], nums[i++]);
else if (nums[i] == 1) i++;
else swap(nums[--r], nums[i]);
}
}
};
排序数组
- 排序数组
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
srand(time(nullptr));
qsort(nums, 0, nums.size() - 1);
return nums;
}
void qsort(vector<int>& nums, int l, int r)
{
if (l >= r) return;
int key = nums[rand() % (r - l + 1) + l]; // 获取随机基准值
int i = l, left = l - 1, right = r + 1;
// 三路划分
while (i < right)
{
if (nums[i] < key) swap(nums[++left], nums[i++]);
else if (nums[i] == key) i++;
else swap(nums[--right], nums[i]);
}
qsort(nums, l, left);
qsort(nums, right, r);
}
};
数组中的第K个最大元素
- 数组中的第K个最大元素
代码语言:javascript代码运行次数:0运行复制最容易想到的就是优先级队列。
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int> pq;
for (auto e : nums) pq.push(e);
int ret = 0;
while (k--)
{
ret = pq.top();
pq.pop();
}
return ret;
}
};
快速选择算法
经常出错:
else return qsort(arr, l, left, k - b - c);
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
srand(time(nullptr));
return qsort(nums, 0, nums.size() - 1, k);
}
int qsort(vector<int>& arr, int l, int r, int k)
{
if (l >= r) return arr[l];
int key = arr[rand() % (r - l + 1) + l]; // 随机基准值
int i = l, left = l - 1, right = r + 1;
// 三路划分
while (i < right)
{
if (arr[i] < key) swap(arr[++left], arr[i++]);
else if (arr[i] == key) i++;
else swap(arr[--right], arr[i]);
}
// 分情况讨论
int c = r - right + 1, b = right - left - 1;
if (c >= k) return qsort(arr, right, r, k);
else if (c + b >= k) return key;
else return qsort(arr, l, left, k - b - c);
}
};
LCR 159. 库存管理 III
- LCR 159. 库存管理 III
代码语言:javascript代码运行次数:0运行复制最先想到的还是优先级队列。
class Solution {
public:
vector<int> inventoryManagement(vector<int>& stock, int cnt) {
priority_queue<int, vector<int>, greater<int>> pq;
for (auto e : stock) pq.push(e);
vector<int> ret;
while (cnt--)
{
ret.push_back(pq.top());
pq.pop();
}
return ret;
}
};
代码语言:javascript代码运行次数:0运行复制快速选择算法。
我就说经常出错吧,这才几分钟…
else qsort(stock, right, r, cnt - a - b);
class Solution {
public:
vector<int> inventoryManagement(vector<int>& stock, int cnt) {
srand(time(nullptr));
qsort(stock, 0, stock.size() - 1, cnt);
return { stock.begin(), stock.begin() + cnt };
}
void qsort(vector<int>& stock, int l, int r, int cnt)
{
if (l >= r) return;
int key = stock[rand() % (r - l + 1) + l];
int i = l, left = l - 1, right = r + 1;
while (i < right)
{
if (stock[i] < key) swap(stock[++left], stock[i++]);
else if (stock[i] == key) i++;
else swap(stock[--right], stock[i]);
}
int a = left - l + 1, b = right - left - 1;
if (a >= cnt) qsort(stock, l, left, cnt);
else if (a + b >= cnt) return;
else qsort(stock, right, r, cnt - a - b);
}
};
3、归并
排序数组
- 排序数组
class Solution {
vector<int> tmp;
public:
vector<int> sortArray(vector<int>& nums) {
int sz = nums.size();
tmp.resize(sz);
MergeSort(nums, 0, sz - 1);
return nums;
}
void MergeSort(vector<int>& arr, int l, int r)
{
if (l >= r) return;
int mid = (l + r) >> 1;
MergeSort(arr, l, mid);
MergeSort(arr, mid + 1, r);
int b1 = l, b2 = mid + 1, i = l;
while (b1 <= mid && b2 <= r)
{
tmp[i++] = arr[b1] < arr[b2] ? arr[b1++] : arr[b2++];
}
while (b1 <= mid) tmp[i++] = arr[b1++];
while (b2 <= r) tmp[i++] = arr[b2++];
for (int i = l; i <= r; i++) arr[i] = tmp[i];
}
};
LCR 170. 交易逆序对的总数
- LCR 170. 交易逆序对的总数
本题要求统计逆序对总数,笼统地说就是找前一部分的数有多少个数大于后一部分的数,那么对于前一部分和后一部分来说有序和乱序都是无所谓的。
代码语言:javascript代码运行次数:0运行复制排升序,找cur2之前有多少个数比我大。
class Solution {
vector<int> tmp;
public:
int reversePairs(vector<int>& record) {
int sz = record.size();
tmp.resize(sz);
return MergeSort(record, 0, sz - 1);
}
int MergeSort(vector<int>& arr, int l, int r)
{
if (l >= r) return 0;
int mid = (l + r) >> 1;
int ret = 0; // 逆序对个数
ret += MergeSort(arr, l, mid);
ret += MergeSort(arr, mid + 1, r);
int b1 = l, b2 = mid + 1, i = l;
while (b1 <= mid && b2 <= r)
{
// 拍升序,找b2之前有多少个数比我大
if (arr[b1] <= arr[b2]) tmp[i++] = arr[b1++];
else
{
tmp[i++] = arr[b2++];
ret += mid - b1 + 1;
}
}
while (b1 <= mid) tmp[i++] = arr[b1++];
while (b2 <= r) tmp[i++] = arr[b2++];
for (int i = l; i <= r; i++) arr[i] = tmp[i];
return ret;
}
};
代码语言:javascript代码运行次数:0运行复制排降序,找cur1之后有多少个数比我小。
class Solution {
vector<int> tmp;
public:
int reversePairs(vector<int>& record) {
int sz = record.size();
tmp.resize(sz);
return MergeSort(record, 0, sz - 1);
}
int MergeSort(vector<int>& arr, int l, int r)
{
if (l >= r) return 0;
int mid = (l + r) >> 1;
int ret = 0; // 逆序对个数
ret += MergeSort(arr, l, mid);
ret += MergeSort(arr, mid + 1, r);
int b1 = l, b2 = mid + 1, i = l;
while (b1 <= mid && b2 <= r)
{
// 排降序,找b1之后有多少个数比我小
if (arr[b1] <= arr[b2]) tmp[i++] = arr[b2++];
else
{
tmp[i++] = arr[b1++];
ret += r - b2 + 1;
}
}
while (b1 <= mid) tmp[i++] = arr[b1++];
while (b2 <= r) tmp[i++] = arr[b2++];
for (int i = l; i <= r; i++) arr[i] = tmp[i];
return ret;
}
};
计算右侧小于当前元素的个数
- 计算右侧小于当前元素的个数
class Solution {
vector<int> ret;
vector<int> index; // 绑定元素和其下标
vector<int> tmp;
vector<int> tmpindex;
public:
vector<int> countSmaller(vector<int>& nums) {
int n = nums.size();
ret.resize(n);
index.resize(n);
tmp.resize(n);
tmpindex.resize(n);
for (int i = 0; i < n; i++) index[i] = i;
MergeSort(nums, 0, n - 1);
return ret;
}
void MergeSort(vector<int>& arr, int l, int r)
{
if (l >= r) return;
int mid = (l + r) >> 1;
MergeSort(arr, l, mid);
MergeSort(arr, mid + 1, r);
int b1 = l, b2 = mid + 1, i = l;
while (b1 <= mid && b2 <= r)
{
if (arr[b1] <= arr[b2])
{
tmp[i] = arr[b2];
tmpindex[i++] = index[b2++]; // 下标和元素同步移动
}
else
{
ret[index[b1]] += r - b2 + 1;
tmp[i] = arr[b1];
tmpindex[i++] = index[b1++];
}
}
while (b1 <= mid)
{
tmp[i] = arr[b1];
tmpindex[i++] = index[b1++];
}
while (b2 <= r)
{
tmp[i] = arr[b2];
tmpindex[i++] = index[b2++];
}
for (int i = l; i <= r; i++)
{
arr[i] = tmp[i];
index[i] = tmpindex[i];
}
}
};
翻转对
- 翻转对
class Solution {
vector<int> tmp;
public:
int reversePairs(vector<int>& nums) {
int n = nums.size();
tmp.resize(n);
return MergeSort(nums, 0, n - 1);
}
int MergeSort(vector<int>& arr, int l, int r)
{
if (l >= r) return 0;
int mid = (l + r) >> 1;
int ret = 0; // 统计翻转对个数
ret += MergeSort(arr, l, mid);
ret += MergeSort(arr, mid + 1, r);
int b1 = l, b2 = mid + 1, i = l;
// 和归并的逻辑不同,在归并之前统计
while (b1 <= mid && b2 <= r)
{
if (arr[b1] / 2.0 <= arr[b2]) b2++; // 做除法,防止溢出
else
{
ret += r - b2 + 1;
b1++;
}
}
b1 = l, b2 = mid + 1;
while (b1 <= mid && b2 <= r)
tmp[i++] = arr[b1] <= arr[b2] ? arr[b2++] : arr[b1++];
while (b1 <= mid) tmp[i++] = arr[b1++];
while (b2 <= r) tmp[i++] = arr[b2++];
for (int k = l; k <= r; k++) arr[k] = tmp[k];
return ret;
}
};
本篇文章的分享就到这里了,如果您觉得在本文有所收获,还请留下您的三连支持哦~
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-04-03,如有侵权请联系 cloudcommunity@tencent 删除intvector排序排序算法数组发布者:admin,转转请注明出处:http://www.yc00.com/web/1747994336a4716441.html
评论列表(0条)