尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
优选算法专题7:分治
分治目录分治试题1颜色分类算法原理代码编写试题2排序数组快排算法原理代码编写试题3数组中的第K个最大元素算法原理代码编写试题4最小的k个数算法原理代码编写试题5排序数组归并算法原理代码编写试题6数组中的逆序对算法原理代码编写试题7计算右侧小于当前元素的个数算法原理代码编写试题8翻转对算法原理代码编写试题1颜色分类算法原理分治分而治之解法三指针代码编写个人版本class Solution { public: void sortColors(vectorint nums) { int left -1, right nums.size(), i 0; while(i right) { if(nums[i] 0) { swap(nums[left], nums[i]); } else if(nums[i] 1) { i; } else { swap(nums[--right], nums[i]); } } } };标准版本class Solution { public: void sortColors(vectorint nums) { int n nums.size(); int left -1, right n, i 0; while(i right) { if(nums[i] 0) swap(nums[left], nums[i]); else if(nums[i] 1) i; else swap(nums[--right],nums[i]); } } };试题2排序数组快排算法原理解法快速排序代码编写class Solution { public: vectorint sortArray(vectorint nums) { srand(time(NULL)); qsort(nums,0,nums.size() - 1); return nums; } void qsort(vectorint nums,int l,int r) { if(l r) { return; } //数组分成三块 int key getRandom(nums,l,r); 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]); } } //[1,left][left 1,right - 1][right,r] qsort(nums,l,left); qsort(nums,right,r); } int getRandom(vectorint nums,int left,int right) { int r rand(); return nums[r % (right - left 1) left]; } };试题3数组中的第K个最大元素算法原理解法一堆排序O(NlogN)解法二快速选择算法O(N)代码编写class Solution { public: int findKthLargest(vectorint nums, int k) { srand(time(NULL)); return qsort(nums,0,nums.size() - 1,k); } int qsort(vectorint nums,int l,int r,int k) { if(l r) { return nums[l]; } //1. 随机选择基准元素 int key getRandom(nums,l,r); //2. 根据基准元素将数组分三块 int left l - 1,right r 1,i l; while(i right) { if(nums[i] key) { swap(nums[left],nums[i]); } else if(nums[i] key) { i; } else { swap(nums[--right],nums[i]); } } //3. 分情况讨论 int c r - right 1; int b ( right - 1 ) - ( left 1 ) 1; if(c k) { return qsort(nums,right,r,k); } else if(b c k) { return key; } else { return qsort(nums,l,left,k - b - c); } } int getRandom(vectorint nums,int left,int right) { return nums[rand() % (right - left 1) left]; } };试题4最小的k个数算法原理解法一排序O(NlogN)解法二大根堆O(NlogK)解法三快速选择算法O(N)随机选择基准元素数组分三块代码编写class Solution { public: vectorint inventoryManagement(vectorint nums, int k) { srand(time(NULL)); qsort(nums, 0, nums.size() - 1, k); return {nums.begin(), nums.begin() k}; } void qsort(vectorint nums, int l,int r,int k) { if(l r) { return; } //1. 随机选择一个基准元素 int key getRandom(nums, l, r); //2.数组分三块 int left l - 1,right r 1,i l; while(i right) { if(nums[i] key) { swap(nums[left],nums[i]); } else if(nums[i] key) { i; } else { swap(nums[--right],nums[i]); } } // [l,left][left1,right-1][right,r] int a left - l 1; int b right - left - 1; if(a k) { qsort(nums, l, left, k); } else if(a b k) { return; } else { qsort(nums, right, r, k - a - b); } } int getRandom(vectorint nums, int l,int r) { return nums[rand() % (r - l 1) l]; } };试题5排序数组归并算法原理代码编写class Solution { vectorint tmp; public: vectorint sortArray(vectorint nums) { tmp.resize(nums.size()); mergeSort(nums, 0, nums.size() - 1); return nums; } void mergeSort(vectorint nums, int left, int right) { if(left right) { return; } //1. 选择中间点划分区间 int mid (left right) 1; //[left, mid] [mid 1, right] //2. 排序左右区间 mergeSort(nums, left, mid); mergeSort(nums, mid 1, right); //3. 合并两个有序数组 int cur1 left,cur2 mid 1, i 0; while(cur1 mid cur2 right) { tmp[i] nums[cur1] nums[cur2] ? nums[cur1] : nums[cur2]; } //4. 处理没有遍历完的数组 while(cur1 mid) { tmp[i] nums[cur1]; } while(cur2 right) { tmp[i] nums[cur2]; } //还原 for(int i left; i right; i) { nums[i] tmp[i - left]; } } };试题6数组中的逆序对算法原理解法一暴力枚举两层for循环解法二归并排序代码编写class Solution { int tmp[50010]; public: int reversePairs(vectorint nums) { return mergeSort(nums, 0, nums.size() - 1); } int mergeSort(vectorint nums, int left, int right) { if(left right) { return 0; } int ret 0; //1. 找中间点将数组分成两份 int mid (left right) 1; //[left, mid][mid 1, right] //2. 左边个数 排序 右边个数 排序 ret mergeSort(nums, left, mid); ret mergeSort(nums, mid 1, right); //3. 一左一右个数 int cur1 left, cur2 mid 1,i 0; while(cur1 mid cur2 right) { if(nums[cur1] nums[cur2]) { tmp[i] nums[cur1]; } else { ret mid - cur1 1; tmp[i] nums[cur2]; } } //4. 处理剩余排序 while(cur1 mid) { tmp[i] nums[cur1]; } while(cur2 right) { tmp[i] nums[cur2]; } //5. 还原 for(int j left; j right; j) { nums[j] tmp[j - left]; } return ret; } };试题7计算右侧小于当前元素的个数算法原理代码编写class Solution { vectorint ret; vectorint index; int tmpNums[500010]; int tmpIndex[500010]; public: vectorint countSmaller(vectorint nums) { int n nums.size(); ret.resize(n); index.resize(n); //初始化index数组 for(int i 0; i n; i) { index[i] i; } mergeSort(nums, 0, n - 1); return ret; } void mergeSort(vectorint nums, int left, int right) { if(left right) { return; } //1. 根据中间元素划分区间 int mid (right left) 1; //[left, mid][mid 1, right] //2. 先处理左右两部分 mergeSort(nums, left, mid); mergeSort(nums, mid 1, right); //3. 处理一左一右 int cur1 left, cur2 mid 1, i 0; while(cur1 mid cur2 right) { if(nums[cur1] nums[cur2]) { tmpNums[i] nums[cur2]; tmpIndex[i] index[cur2]; } else { ret[index[cur1]] right - cur2 1; tmpNums[i] nums[cur1]; tmpIndex[i] index[cur1]; } } //4. 处理剩下排序 while(cur1 mid) { tmpNums[i] nums[cur1]; tmpIndex[i] index[cur1]; } while(cur2 right) { tmpNums[i] nums[cur2]; tmpIndex[i] index[cur2]; } //5. 还原 for(int j left; j right; j) { nums[j] tmpNums[j - left]; index[j] tmpIndex[j - left]; } } };试题8翻转对算法原理解法一暴力枚举解法二分治代码编写降序策略class Solution { int tmp[50010]; public: int reversePairs(vectorint nums) { return mergeSort(nums, 0, nums.size() - 1); } int mergeSort(vectorint nums, int left, int right) { if(left right) { return 0; } int ret 0; //1. 找中间点划分区间 int mid (left right) 1; //2. 计算左右两侧翻转对 ret mergeSort(nums, left, mid); ret mergeSort(nums,mid 1, right); //3. 计算一左一右翻转对数量 int cur1 left, cur2 mid 1, i left; while(cur1 mid) { while(cur2 right nums[cur2] nums[cur1] / 2.0) { cur2; } if(cur2 right) { break; } ret right - cur2 1; cur1; } //4. 合并两个有序数组 cur1 left, cur2 mid 1; while(cur1 mid cur2 right) { tmp[i] nums[cur1] nums[cur2] ? nums[cur2] : nums[cur1]; } while(cur1 mid) { tmp[i] nums[cur1]; } while(cur2 right) { tmp[i] nums[cur2]; } //5. 还原 for(int j left; j right; j) { nums[j] tmp[j]; } return ret; } };升序策略class Solution { int tmp[50010]; public: int reversePairs(vectorint nums) { return mergeSort(nums, 0, nums.size() - 1); } int mergeSort(vectorint nums, int left, int right) { if(left right) { return 0; } int ret 0; //1. 找中间点划分区间 int mid (left right) 1; //2. 计算左右两侧翻转对 ret mergeSort(nums, left, mid); ret mergeSort(nums,mid 1, right); //3. 计算一左一右翻转对数量 int cur1 left, cur2 mid 1, i left; while(cur2 right) { while(cur1 mid nums[cur2] nums[cur1] / 2.0) { cur1; } if(cur1 mid) { break; } ret mid - cur1 1; cur2; } //4. 合并两个有序数组 cur1 left, cur2 mid 1; while(cur1 mid cur2 right) { tmp[i] nums[cur1] nums[cur2] ? nums[cur1] : nums[cur2]; } while(cur1 mid) { tmp[i] nums[cur1]; } while(cur2 right) { tmp[i] nums[cur2]; } //5. 还原 for(int j left; j right; j) { nums[j] tmp[j]; } return ret; } };
RELATED

相关推荐

openclaw(小龙虾)

openclaw(小龙虾)

openclaw(小龙虾) 一、什么是openclaw openclaw是一个可以执行具体任务的AI智能体,让AI不仅仅停留在问答阶段,能真正帮助我们处理一些事情。 注意:小龙虾存在安全风险,请使用私人电脑进行操作。 需要nodejs…

📅 2026/10/8 3:41:25
PM项目管理-权利利益模型

PM项目管理-权利利益模型

📅 2026/10/3 15:54:00
vivado报错及解决【十】

vivado报错及解决【十】

ERROR: [Synth 8-1766] cannot open include file include.v这个错误是我们在引用类似以下的参数文件时,vivado系统找不到文件导致的。include "params.v"AMD官方的解决方案如下:AMD官方论坛提供了两种解决方案:1.将include.v文件设…

📅 2026/10/4 4:47:29
MORE NEWS

更多资讯

📰

宜阳县电工证丢了怎么补办保姆级教程:缺证就缺饭碗,这份教程帮你稳稳上岗

宜阳县电工证丢了怎么补办保姆级教程:缺证就缺饭碗,这份教程帮你稳稳上岗 你是不是正愁着手上没电工证,找工作处处碰壁?宜阳县电工证丢了补办流程复杂又耗时,但要是不补,工作机会可能就溜走了。别急,这是一份保姆级的补办教程,帮你快速恢复证件,重新…

📰

原阳电工证考试时间怎么安排 上岗必备干货全在这里

原阳电工证考试时间怎么安排 上岗必备干货全在这里 工地太忙根本没时间复习考试,这是很多电工从业者的真实写照,尤其是刚转岗的小伙伴,既要面对繁重的施工任务,又要为原阳电工证考试时间做准备,焦虑感直接拉满。原阳电工证考试时间每年固定安排在几个时…

📰

高级电工证比大专好吗?内部消息:实操考试心里没底怕挂科别慌

高级电工证比大专好吗?内部消息:实操考试心里没底怕挂科别慌 实操考试心里没底怕挂科,这几乎是每个准备考电工证的人心头最大的疙瘩。尤其像开封房建工程这样的岗位,电工证不仅是上岗门槛,更是你职业发展的敲门砖。但很多人会纠结:“…

📰

高处作业特种工实操考试心里没底怕挂科?保姆级教程帮你一次过

高处作业特种工实操考试心里没底怕挂科?保姆级教程帮你一次过 你是不是正盯着“高处作业特种工”的实操考试发愁?担心自己操作不规范、细节没掌握好,一不小心就挂科?别急,本文就是你急需的 保姆级教程…

📰

原阳电工证考试时间保姆级教程:外省证能转吗?附薪资前景全解析

原阳电工证考试时间保姆级教程:外省证能转吗?附薪资前景全解析 之前考的证在外省能不能转过来?这个事别急,咱们一步步来。特别是你手上拿着的电工证,不管是高压还是低压,现在都越来越吃香,但很多人因为不了解政策,错失了不少机会。别担心,今天就给你…

📰

电工证怎么审核毕业证 上岗必备的硬门槛别踩坑

电工证怎么审核毕业证 上岗必备的硬门槛别踩坑 找工作时缺的不是力气,是资格证,特别是电工证,这几乎是很多岗位的“上岗必备”。很多人以为考个电工证简单,但其实从报名、审核毕业证到考试、复审,每一步都有讲究。特别是毕业证审核这块,很多人因为不了…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬