void moveZeroes(vector<int>& nums) { //申请一个辅助数组,存放非零元素,然后再赋值给原数组 vector<int> aux; for(int i=0;isize();i++){ if(nums[i]) aux.push_back(nums[i]);//借用向量的push_back函数 } for(int i=0;isize();i++){ nums[i]=aux[i]; } //补0 for(int i=aux.size();isize();i++){ nums[i]=0; } }很简单的一个思路:
申请额外数组存储原数组非零元素(利用push_back),然后赋值回给原数组,最后在末位编变成0
法二:
void moveZeroes(vector<int>& nums) { /* 原地实现该功能,不申请额外空间: 定义一个索引k,指向数组第一个元素,i用于遍历数组,如果是非零元素把值赋给k位置。 k更新到下一个位置,直至遍历结束,从k开始往后补0 */ int k=0;//nums中[0,k)存储非零元素 //for循环,不断把非零元素依次赋值给k for(int i=0;isize();i++) if(nums[i]){//nums[i]不为0 nums[k++]=nums[i];//别忘了移动k索引 } //补零 for(int i=k;isize();i++) nums[i]=0; }法三:零与非零的交换
void moveZeroes(vector<int>& nums) { int k=0;//nums中[0,k)存储非零元素 for(int i=0;isize();i++) if(nums[i]){ swap(nums[i],nums[k]); k++; } }与法二相比,由于直接交换,少了重新赋值为0操作
优化细节:
避免自己和自己交换,可以考虑i与k的大小关系
if(i!=k) swap(nums[k++],nums[i]);
else k++;
void sortColors(vector<int>& nums) { /* 因为元素只有0,1,2三种可能,所以采用计数排序思想: 分别统计出:0的个数,1的个数以及2的个数,赋值即可 */ int count[3]={0}; for(int i=0;isize();i++){ assert(nums[i]>=0&&nums[i]<=2); count[nums[i]]++;//数值直接对应频次 } //定义一个不断累计的索引 int index=0; for(int i=0;i0];i++) nums[index++]=0; for(int i=0;i1];i++) nums[index++]=1; for(int i=0;i2];i++) nums[index++]=2; }几个代码小细节:
- 因为只有0,1,2且想累计出现个数,直接以元素值计算频次
- 由于从头一次按照个数赋值0,1,2;所以直接建立一个不断累计的index
其实可以把三路快排的思想移到这
这是最后想达到的效果:
其实关键在于对遍历索引i的元素处理:
分以下三种情况:
如果元素为1,i右移
如果元素是2,和two前一个元素交换,i不动,two--
如果元素是1,和zero后元素交换,zero++,i++
代码实现
#include #include using namespace std; class soluction{ public: void sortColors(vector<int>& nums){ /* 功能实现: [0,zero]全是0----也就是zero初始化为-1 [two,n-1]全是1---也就是two初始化为n(假设nums长度为n) 索引i遍历数组,遇到1右移,控制(zero,two)范围全是1 */ int zero=-1; int two=nums.size(); int i=0;//从头遍历数组 while( i//遍历结束条件 if(nums[i]==1) i++; else if(nums[i]==2){ two--; swap(nums[two],nums[i]); } else{//nums[i]==0 zero++; swap(nums[i],nums[zero]); i++; } } } }; int main(){ int arr[]={1,0,2,0,2,1,1,2,0}; vector<int> vec(arr,arr+sizeof(arr)/sizeof(int)); soluction().sortColors(vec); for(vector<int>::iterator it=vec.begin();it!=vec.end();it++) cout<<(*it)<<" "; }
- #include
- #include
- using namespace std;
- int partition(vector<int>& a,int L,int R){
- /*
- 索引i记录小于基准元素的最后一个位置,初始化为基准元素位置
- 索引j用于遍历
- j遇到的元素≥基准元素---往后遍历
- j遇到的元素<基准元素---交换i后位置和当前位置,i++
- */
- int e=a[L];//以最左边元素为基准元素
- int i=L;
- int j=L+1;
- for(;j<=R;j++){
- if(a[j]
- swap(a[++i],a[j]);
- }
- }
- swap(a[L],a[i]);
- return i;
- }
- void quickSortHelper(vector<int>& a,int L,int R){
- if(L>=R) return;//递归结束
- int p=partition(a,L,R);
- quickSortHelper(a,L,p-1);
- quickSortHelper(a,p+1,R);
- }
- void quickSort(vector<int>& a){//一定要加&
- quickSortHelper(a,0,a.size()-1);
- }
- int main(){
- vector<int> arr={1,22,3,55,66,7,2,11,1,3,4};
- quickSort(arr);
- vector<int>::iterator it;
- for(it=arr.begin();it!=arr.end();it++){
- cout<<(*it)<<" ";
- }
- return 0;
- }
注意要在vector加上*,否则原向量不改变
- /*
- 双指针法:
- i不断右移,使得其之前的元素均≤基准元素
- j不断左移,使得其之后的元素均≥基准元素
- 如果i,j均停止,交换两者所指元素,然后i右移,j左移
- 最后----把j位置,即小于基准元素最后一个元素和基准元素交换
- */
- int e=a[L];
- int i=L+1,j=R;//i,j指向除基准元素的两头
- while(1){
- while(i<=j&&a[i]<=e) i++;
- while(i<=j&&a[j]>=e) j--;
- if(i>j) break;
- swap(a[i++],a[j--]);
- }
- swap(a[L],a[j]);
- return j;
- }
三:寻找第k个大的元素

这里要用到一个快速排序分区的性质:
每次快排后,都可以确定该元素在顺序中的正确位置。
也就是说:排序后,倒数第一个最大,倒数第二个第二大。。。。
只要快排的索引落在了该位置,该位置就可以确定第几大或第几小
- int partition(vector<int>& nums,int l,int r){
- int e=nums[l];
- int i=l;
- int j=l+1;
- for(;j<=r;j++){
- if(nums[j]
- swap(nums[j],nums[++i]);
- }
- swap(nums[l],nums[i]);
- return i;
- }
- int findKthLargest(vector<int>& nums, int k) {
- int target=nums.size()-k;
- int l=0;
- int r=nums.size()-1;
- while(1){//条件:L<=R,但是该题一定有解,无需判断
- int p=partition(nums,l,r);
- if(p==target) return nums[p];
- else if(p>target) r=p-1;
- else l=p+1;
- }
- }
-
相关阅读:
CentOS 8里的这个功能,天翼云SFS弹性文件校准了
智慧工地管理系统(Smart site management system)源码
Hadoop架构、Hive相关知识点及Hive执行流程
Go-Excelize API源码阅读(三十六)——SetSheetRow、InsertPageBreak
悬赏任务兼职众人帮蚂蚁帮扶任务平台
集成学习-Boosting
没有二十年功力,写不出Thread.sleep(0)这一行“看似无用”的代码!
vue前端开发ios系统:https发http请求 网络通讯之间的安全问题
Spark写入支持更新【源码二次开发】
国内BLDC电机控制方案目前存在什么痛点?
-
原文地址:https://blog.csdn.net/weixin_47173597/article/details/126771057