【C++刷题】优选算法——分治

  1. 颜色分类
void sortColors(vector<int>& nums)
{
    int left = -1, right = nums.size();
    for (int i = 0; i < right;) {
        if (nums[i] == 0) {
            swap(nums[++left], nums[i++]);
        } else if (nums[i] == 2) {
            swap(nums[--right], nums[i]);
        } else {
            ++i;
        }
    }
}
  1. 排序数组
// 快速排序
void quick_sort(vector<int>& nums, int start, int end) {
    if (start >= end) return;

    int key = nums[rand() % (end - start + 1) + start];
    int left = start - 1, right = end + 1;
    for (int i = start; i < right;) {
        if (nums[i] < key) {
            swap(nums[++left], nums[i++]);
        } else if(nums[i] > key) {
            swap(nums[--right], nums[i]);
        } else {
            ++i;
        }
    }
    quick_sort(nums, start, left);
    quick_sort(nums, right, end);
}
vector<int> sortArray(vector<int>& nums) {
    srand(time(nullptr));
    quick_sort(nums, 0, nums.size() - 1);
    return nums;
}

// 归并排序
vector<int> tmp;
void merge_sort(vector<int>& nums, int start, int end) {
    if (start >= end) return;

    int mid = start + (end - start) / 2;
    merge_sort(nums, start, mid);
    merge_sort(nums, mid + 1, end);
    int left = start, right = mid + 1, i = start;
    while (left <= mid && right <= end) {
        if (nums[left] < nums[right]) {
            tmp[i++] = nums[left++];
        } else {
            tmp[i++] = nums[right++];
        }
    }
    while (left <= mid) {
        tmp[i++] = nums[left++];
    }
    while (right <= end) {
        tmp[i++] = nums[right++];
    }
    for (int i = start; i <= end; ++i) {
        nums[i] = tmp[i];
    }
}

vector<int> sortArray(vector<int>& nums) {
    tmp = vector<int>(nums.size());
    merge_sort(nums, 0, nums.size() - 1);
    return nums;
}
  1. 数组中的第K个最大元素
void quick_sort(vector<int>& nums, int start, int end, int k) {
    if (start >= end) return;

    int key = nums[rand() % (end - start + 1) + start];
    int left = start - 1, right = end + 1;
    for (int i = start; i < right;) {
        if (nums[i] > key) {
            swap(nums[++left], nums[i++]);
        } else if(nums[i] < key) {
            swap(nums[--right], nums[i]);
        } else {
            ++i;
        }
    }
    int a = left + 1, b = right - a;
    if (a >= k) {
        quick_sort(nums, start, left, k);
    } else if (a + b >= k) {
        return;
    } else {
        quick_sort(nums, right, end, k);
    }
}
int findKthLargest(vector<int>& nums, int k) {
    srand(time(nullptr));
    quick_sort(nums, 0, nums.size() - 1, k);
    return nums[k - 1];
}
  1. 库存管理 III
void quick_sort(vector<int>& stock, int start, int end, int cnt) {
    if (start >= end) return;

    int key = stock[rand() % (end - start + 1) + start];
    int left = start - 1, right = end + 1;
    for (int i = start; i < right;) {
        if (stock[i] < key) {
            swap(stock[++left], stock[i++]);
        } else if (stock[i] > key) {
            swap(stock[--right], stock[i]);
        } else {
            ++i;
        }
    }
    int a = left + 1, b = right - a;
    if (a >= cnt) {
        quick_sort(stock, start, left, cnt);
    } else if (a + b >= cnt) {
        return;
    } else {
        quick_sort(stock, right, end, cnt);
    }
}
vector<int> inventoryManagement(vector<int>& stock, int cnt) {
    srand(time(nullptr));
    quick_sort(stock, 0, stock.size() - 1, cnt);
    return vector<int>(stock.begin(), stock.begin() + cnt);
}
  1. 交易逆序对的总数
int count = 0;
vector<int> tmp;
void merge_sort(vector<int>& record, int start, int end) {
    if (start >= end) return;

    int mid = start + (end - start) / 2;
    merge_sort(record, start, mid);
    merge_sort(record, mid + 1, end);
    int left = start, right = mid + 1, i = start;
    while (left <= mid && right <= end) {
        if (record[left] > record[right]) {
            tmp[i++] = record[left++];
            count += (end - right + 1); // 灵魂之解
        } else {
            tmp[i++] = record[right++];
        }
    }
    while (left <= mid) {
        tmp[i++] = record[left++];
    }
    while (right <= end) {
        tmp[i++] = record[right++];
    }
    for (int i = start; i <= end; ++i) {
        record[i] = tmp[i];
    }
}
int reversePairs(vector<int>& record) {
    tmp.resize(record.size());
    merge_sort(record, 0, record.size() - 1);
    return count;
}
  1. 计算右侧小于当前元素的个数
vector<int> ret, index, tmp_index, tmp_nums;
void merge_sort(vector<int>& nums, int start, int end) {
    if (start >= end) return;

    int mid = start + (end - start) / 2;
    merge_sort(nums, start, mid);
    merge_sort(nums, mid + 1, end);

    int left = start, right = mid + 1, i = start;
    while (left <= mid && right <= end) {
        if (nums[left] > nums[right]) {
            tmp_nums[i] = nums[left];
            tmp_index[i] = index[left];
            ret[index[left]] += (end - right + 1);
            ++i;++left;
        } else {
            tmp_nums[i] = nums[right];
            tmp_index[i] = index[right];
            ++i;++right;
        }
    }
    while (left <= mid) {
        tmp_nums[i] = nums[left];
        tmp_index[i] = index[left];
        ++i;++left;
    }
    while (right <= end) {
        tmp_nums[i] = nums[right];
        tmp_index[i] = index[right];
        ++i;++right;
    }
    for (int i = start; i <= end; ++i) {
        nums[i] = tmp_nums[i];
        index[i] = tmp_index[i];
    }
}
vector<int> countSmaller(vector<int>& nums) {
    int n = nums.size();
    index.resize(n);
    for (int i = 0; i < n; ++i) {
        index[i] = i;
    }
    ret.resize(n);
    tmp_nums.resize(n);
    tmp_index.resize(n);

    merge_sort(nums, 0, nums.size() - 1);
    return ret;
}
  1. 翻转对
int count = 0;
vector<int> tmp;
void merge_sort(vector<int>& nums, int start, int end) {
    if (start >= end) return;

    int mid = start + (end - start) / 2;
    merge_sort(nums, start, mid);
    merge_sort(nums, mid + 1, end);

    int left = start, right = mid + 1;
    while (left <= mid && right <= end) {
        if (nums[left] > 2 * (long long)nums[right]) {
            count += (end - right + 1);
            ++left;
        } else {
            ++right;
        }
    }
    left = start, right = mid + 1;
    int i = start;
    while (left <= mid && right <= end) {
        if (nums[left] > nums[right]) {
            tmp[i++] = nums[left++];
        } else {
            tmp[i++] = nums[right++];
        }
    }
    while (left <= mid) tmp[i++] = nums[left++];
    while (right <= end) tmp[i++] = nums[right++];

    for (int i = start; i <= end; ++i) {
        nums[i] = tmp[i];
    }
}
int reversePairs(vector<int>& nums) {
    tmp.resize(nums.size());
    merge_sort(nums, 0, nums.size() - 1);
    return count;
}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C++中,algorithm和numeric库中有几个常用的模板函数可以用于刷题,包括swap,reverse,sort,unique和accumulate。 1. swap(): 这个函数可以交换两个变量的值。它的模板定义如下: ```cpp template <class T> void swap(T& a, T& b) { T c(a); a = b; b = c; } ``` 通过调用swap()函数,可以交换两个变量的值。 2. reverse(): 这个函数可以反转容器中元素的顺序。例如,可以使用reverse()函数反转一个vector容器中的元素。 3. sort(): 这个函数可以对容器中的元素进行排序。可以通过提供一个比较函数来指定排序的规则。比如,可以使用sort()函数对一个vector容器中的元素进行升序排序或者降序排序。 4. unique(): 这个函数可以去除容器中的重复元素,并返回指向新的逻辑尾部的迭代器。需要注意的是,在调用unique()函数之前,需要先对容器进行排序。 5. accumulate(): 这个函数可以对容器中的元素进行累加操作,并返回累加结果。accumulate()函数接受三个参数:容器的起始迭代器、容器的结束迭代器和一个初始值。可以使用accumulate()函数计算数组或者vector容器中元素的和。 以上是C++中一些常用的算法函数,可以在刷题过程中使用它们来简化代码并提高效率。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [C++ LeetCode刷题常用函数](https://blog.csdn.net/qq_40876059/article/details/126245632)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿阿阿顺Yaya

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值