C++ topK算法模板

C++ topK算法 – 基于快速选择实现

算法功能描述:
返回数组nums中第K小的元素。

算法工作机制描述:
选择数组nums最左边的数数字作为锚点:大于nums[l]的元素移到nums[l]右边,小于nums[l]的元素移到nums[l]左边。


int getTopK(vector<int>& nums, int l, int r, int K) {
        int i = l, j = r;
        while (i < j) {
            while (i < j && nums[j] >= nums[l]) --j;  
            while (i < j && nums[i] <= nums[l]) ++i;
            swap(nums[i], nums[j]); 
        }
        swap(nums[i], nums[l]);

        if (i == K) return nums[K];
        else if (i < K) return getMid(nums, i + 1, r, K);
        else return getMid(nums, l, i - 1, K);
    }
<think>好的,用户正在寻找C++相关的GESP五级算法模板合集。首先,我需要确认GESP五级考试的具体内容和要求。根据引用[2],五级考点包括贪心选择性质、最优子结构,以及相关的算法如区间调度、背包问题等。此外,练习题涉及排队接水、线段覆盖和合并果子,这些都是典型的贪心算法应用。 用户需要的是算法模板,因此我需要整理五级考试中常见的算法类型,并提供对应的C++代码示例。首先,贪心算法是重点,比如区间调度和背包问题。然后,可能涉及分治算法,如快速排序和归并排序,这些在数据处理中常用。动态规划也是高级算法的一部分,比如背包问题的最优解。另外,优先队列(堆结构)在合并果子这类题目中有应用,需要提供相应的实现方法。 接下来,我需要确保每个算法模板符合C++语法,并且结构清晰,便于用户理解和应用。例如,贪心算法的区间调度需要按结束时间排序,背包问题则涉及价值密度排序。分治算法中的快速排序和归并排序需要展示递归实现。动态规划部分,01背包问题需要二维数组存储状态。优先队列则可以利用STL中的priority_queue来简化代码。 同时,根据引用[2]中的建议,复杂度分析也很重要,因此每个模板后需要添加时间和空间复杂度的说明,帮助用户评估算法效率。此外,用户可能希望了解如何应用这些模板解决实际问题,所以相关问题部分需要包括算法选择、优化方法和应用场景等,促进深入理解。 最后,需要检查是否有遗漏的考点或常见算法,确保模板合集全面覆盖GESP五级的要求。例如,引用[2]提到的递归与分治优化,如记忆化剪枝,可能需要简要提及。链表和高精度计算虽然重要,但用户主要需求是算法模板,因此可能不在当前重点范围内,但需确认是否需简要提及。 总结步骤:整理五级考点涉及的算法类型,编写对应的C++模板,添加复杂度分析,生成相关问题,确保引用正确,并保持回答结构清晰。</think>### GESP五级C++算法模板合集 根据GESP五级考试大纲[^2],核心算法包括贪心策略、分治算法、动态规划和数据结构应用。以下是关键算法模板及实现: --- #### 一、贪心算法模板 1. **区间调度问题**(最多不重叠区间) ```cpp #include <vector> #include <algorithm> using namespace std; int intervalSchedule(vector<vector<int>>& intervals) { sort(intervals.begin(), intervals.end(), [](auto& a, auto& b){ return a[1] < b[1]; // 按结束时间升序 }); int count = 0, end = -1; for (auto& inv : intervals) { if (inv[0] >= end) { count++; end = inv[1]; } } return count; } ``` **复杂度**:$O(n \log n)$(排序主导) --- 2. **分数背包问题** ```cpp double fractionalKnapsack(int capacity, vector<pair<int, int>>& items) { sort(items.begin(), items.end(), [](auto& a, auto& b) { return (double)a.second/a.first > (double)b.second/b.first; // 按价值密度排序 }); double total = 0.0; for (auto& item : items) { if (capacity >= item.first) { total += item.second; capacity -= item.first; } else { total += (double)capacity * item.second / item.first; break; } } return total; } ``` --- #### 二、分治算法模板 1. **快速排序** ```cpp void quickSort(int arr[], int left, int right) { if (left >= right) return; int i = left, j = right, pivot = arr[(left + right)/2]; while (i <= j) { while (arr[i] < pivot) i++; while (arr[j] > pivot) j--; if (i <= j) swap(arr[i++], arr[j--]); } quickSort(arr, left, j); quickSort(arr, i, right); } ``` **复杂度**:平均$O(n \log n)$,最坏$O(n^2)$ --- 2. **归并排序** ```cpp void merge(int arr[], int l, int mid, int r) { vector<int> tmp(r - l + 1); int i = l, j = mid + 1, k = 0; while (i <= mid && j <= r) tmp[k++] = arr[i] < arr[j] ? arr[i++] : arr[j++]; while (i <= mid) tmp[k++] = arr[i++]; while (j <= r) tmp[k++] = arr[j++]; for (int m = 0; m < tmp.size(); m++) arr[l + m] = tmp[m]; } void mergeSort(int arr[], int l, int r) { if (l >= r) return; int mid = l + (r - l)/2; mergeSort(arr, l, mid); mergeSort(arr, mid + 1, r); merge(arr, l, mid, r); } ``` **复杂度**:稳定$O(n \log n)$ --- #### 三、动态规划模板 **01背包问题** ```cpp int knapsack01(int W, vector<int>& wt, vector<int>& val) { int n = wt.size(); vector<vector<int>> dp(n + 1, vector<int>(W + 1, 0)); for (int i = 1; i <= n; i++) { for (int w = 1; w <= W; w++) { if (wt[i-1] > w) dp[i][w] = dp[i-1][w]; else dp[i][w] = max(dp[i-1][w], val[i-1] + dp[i-1][w - wt[i-1]]); } } return dp[n][W]; } ``` **复杂度**:$O(nW)$ --- #### 四、优先队列应用 **合并果子(Huffman编码)** ```cpp #include <queue> using namespace std; int mergeFruits(vector<int>& fruits) { priority_queue<int, vector<int>, greater<int>> pq; // 小顶堆 for (int f : fruits) pq.push(f); int total = 0; while (pq.size() > 1) { int a = pq.top(); pq.pop(); int b = pq.top(); pq.pop(); total += a + b; pq.push(a + b); } return total; } ``` **复杂度**:$O(n \log n)$ --- ### 相关练习建议 1. 实现模板后尝试对应题库:[P1223]排队接水、[P1803]线段覆盖 2. 通过修改模板参数适应不同输入规模 3. 添加调试语句观察中间状态变化 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值