变量简洁正确完整思路 排序,遍历数组nums更新差值答案ans class Solution { public: int maximumGap(vector<int>& nums) { int n=nums.size(); sort(nums.begin(),nums.end()); int ans=0; for(int i=1;i<n;i++){ ans=max(ans,nums[i]-nums[i-1]); } return ans; } }; 冒泡排序 变量简洁正确完整思路 i-1已经处理好,i需要处理,逆序j让最小值逐渐交换到i,ok一开始=true,如果j一次都未交换ok没有变过退出i循环 class Solution { public: int maximumGap(vector<int>& nums) { int n=nums.size(); for(int i=0;i<n;i++){ bool ok=true; for(int j=n-2;j>=i;j--){ ok=false; if(nums[j]>nums[j+1])swap(nums[j],nums[j+1]); } if(ok)break; } int ans=0; for(int i=1;i<n;i++){ ans=max(ans,nums[i]-nums[i-1]); } return ans; } }; 快速排序 dfs形参begend,将begend数组排序完毕,基准数nums[beg],左右哨兵ij,j向中间找到小于nums[beg]的数,i向中间找到大于nums[beg]的数,交换ij,ij继续向中间找,直到i==j交换nums[beg],nums[i],这样基准数处理完毕,左边小于基准数,右边大于基准数,已经将基准数处理完毕,只需要dfs(beg,i-1)dfs(i+1,end)将基准数左右两段数组都排序完毕就行,ifbeg<=end边界返回 class Solution { public: int maximumGap(vector<int>& nums) { int n=nums.size(); dfs(0,n-1,nums); int ans=0; for(int i=1;i<n;i++){ ans=max(ans,nums[i]-nums[i-1]); } return ans; } void dfs(int beg,int end,vector<int>&nums){ if(beg>end)return; int i=beg,j=end; while(i<j){ while(nums[j]>=nums[beg]&&j>i)j--; while(nums[i]<=nums[beg]&&i<j)i++; if(i<j)swap(nums[i],nums[j]); } swap(nums[beg],nums[i]); dfs(beg,i-1,nums); dfs(i+1,end,nums); } }; 插入排序 j是需要处理的元素的,i=j-1是已经处理好的数组,tmp=nums[j],逆向遍历i,while nums[i]>tmp,nums[i]就应该在tmp后面,nums[i+1]=nums[i],否则,nums[i]<=tmp,nums[i]应该在tmp前面,nums[i+1]=tmp class Solution { public: int maximumGap(vector<int>& nums) { int n=nums.size(); for(int j=1;j<n;j++){ int i=j-1; int tmp=nums[j]; while(i>=0&&nums[i]>tmp){ nums[i+1]=nums[i]; i--; } nums[i+1]=tmp; } int ans=0; for(int i=1;i<n;i++){ ans=max(ans,nums[i]-nums[i-1]); } return ans; } }; 希尔排序 增量inc从n/2开始每次减半,直到1,对于每个inc,相同inc间隔的元素当做一个数组, 数组下标是0,inc,2inc和1,1+inc,1+2inc,inc-1和inc-1+inc,inc-1+2inc等 k是每个数组的第一个元素下标0,1,inc-1,对每个数组进行插入排序,j是需要处理 的元素,i=j-inc是已经处理好的数组,tmp=nums[j],逆向遍历i,while nums[[i] >tmp,nums[i]就应该在tmp后面,nums[i+inc]=nums[i],否则,nums[i]<=tmp, nums[i]应该在tmp前面,nums[i+inc]=tmp; class Solution { public: int maximumGap(vector<int>& nums) { int n=nums.size(); for(int inc=n/2;inc>=1;inc/=2){ for(int k=0;k<=inc-1;k++){ for(int j=k+inc;j<n;j+=inc){ int i=j-inc; int tmp=nums[j]; while(i>=k&&nums[i]>tmp){ nums[i+inc]=nums[i]; i-=inc; } nums[i+inc]=tmp; } } } int ans=0; for(int i=1;i<n;i++){ ans=max(ans,nums[i]-nums[i-1]); } return ans; } }; 选择排序 i需要处理,i-1已经处理好,需要右边一个最小数下标min,j从i右边 找到最小数下标min与i交换 class Solution { public: int maximumGap(vector<int>& nums) { int n=nums.size(); for(int i=0;i<n;i++){ int min=i; for(int j=i+1;j<n;j++){ if(nums[j]<nums[min])min=j; } swap(nums[i],nums[min]); } int ans=0; for(int i=1;i<n;i++){ ans=max(ans,nums[i]-nums[i-1]); } return ans; } }; 堆排序 i需要处理,i-1已经大根堆,cur=i是可能破坏大根堆的节点,fa=(cur-1)/2,while nums[cur]>nums[fa]说明cur破坏了大根堆,swap(nums[cur],nums[fa]),然后cur 更新为fa,继续检测cur是否破坏大根堆,处理完i数组是一个大根堆 j及j右边是已经排序好,逆向for遍历j,swap(nums[0],nums[j-1]),恢复大根堆 heapify(nums,int cur=0,n=j-1),cur是可能破坏大根堆的节点,left=2*cur+1 right=2*cur+2,while()处理cur,找出cur,left,right最大的索引largestIndex largestIndex是curbreak,否则swap(nums[largestIndex],nums[cur]) cur=largestIndex继续判断 class Solution { public: int maximumGap(vector<int>& nums) { int n=nums.size(); for(int i=0;i<n;i++){ int cur=i; int fa=(cur-1)/2; while(nums[cur]>nums[fa]){ swap(nums[cur],nums[fa]); cur=fa; fa=(cur-1)/2; } } for(int j=n;j>=1;j--){ swap(nums[0],nums[j-1]); heapify(nums,0,j-1); } int ans=0; for(int i=1;i<n;i++){ ans=max(ans,nums[i]-nums[i-1]); } return ans; } void heapify(vector<int>&nums,int cur,int n){ int left=cur*2+1,right=cur*2+2; while(left<n){ int largestIndex=(nums[cur]>=nums[left])?cur:left; if(right<n&&nums[right]>nums[largestIndex])largestIndex=right; if(largestIndex==cur)break; swap(nums[cur],nums[largestIndex]); cur=largestIndex; left=cur*2+1,right=cur*2+2; } } }; 归并排序 dfs形参beg end将数组begend排序完毕,如果beg>=end直接返回,mid=beg+(end-beg)/2 dfs(beg,mid)dfs(mid+1,end)将begmid排序,mid+1,end排序,只需将两个有序数组 合并,《合并两个有序数组》,right是已经,cur1是需要cur2是需要,防止覆盖,逆向,大的right--放进去,-- class Solution { public: int maximumGap(vector<int>& nums) { int n=nums.size(); dfs(nums,0,n-1); int ans=0; for(int i=1;i<n;i++){ ans=max(ans,nums[i]-nums[i-1]); } return ans; } void dfs(vector<int>&nums,int beg,int end){ if(beg>=end)return; int mid=beg+(end-beg)/2; dfs(nums,beg,mid); dfs(nums,mid+1,end); vector<int>nums2(nums.begin()+mid+1,nums.begin()+end+1); merge(nums,beg,mid,end,nums2,end-mid); } void merge(vector<int>&nums1,int beg,int mid,int end,vector<int>&nums2,int n){ int right=end+1,cur1=mid,cur2=n-1; while(1){ if(cur1==beg-1&&cur2==-1)return ; else if(cur1==beg-1&&cur2!=-1){ right--; nums1[right]=nums2[cur2]; cur2--; } else if(cur1!=beg-1&&cur2==-1)return ; else if(nums1[cur1]>=nums2[cur2]){ right--; nums1[right]=nums1[cur1]; cur1--; } else if(nums1[cur1]<nums2[cur2]){ right--; nums1[right]=nums2[cur2]; cur2--; } } } }; 踩过的坑 超级大坑!!!!!nums2非常正常,和《合并两个有序数组》一样,但是 nums1非常不一样,起点是beg,beg不是0,cur1=beg-1才能退出而不是-1,同时, right=end+1而不是nums的终点,end-1不是nums的终点,这是递归 计数排序 找出最大值max最小值min,计数for(int num:nums) count[num-min]++; 遍历count i,清数whilecount[i]>0就ans[j++]=i+min, count-- class Solution { public: int maximumGap(vector<int>& nums) { int n=nums.size(); int minNum=nums[0],maxNum=nums[0]; for(int num:nums){ minNum=min(minNum,num); maxNum=max(maxNum,num); } vector<int>count(maxNum-minNum+1,0); for(int num:nums)count[num-minNum]++; int j=0; for(int i=0;i<maxNum-minNum+1;i++){ while(count[i]>0){ nums[j++]=i+minNum; count[i]--; } } int ans=0; for(int i=1;i<n;i++){ ans=max(ans,nums[i]-nums[i-1]); } return ans; } }; 踩过的坑 new int[maxNum-minNum+1]{0}否则不会是0,或者直接用vector速度一样 基数排序 找出最大元素maxNum,求出最大位数maxBit,从个位i=0place=1开始,创建桶count[10], 分配桶,遍历按个位放进count[(nums[j]/place)%10]++, 转化count坐标,将count[j]值转化为最后一个元素的 在数组第几个元素,count0表示空,count1表示第一个元素 ,比如count[0]=3 :20 10 30 表示30在数组中第3个元素,count{1]=5 :51 21 表示 21在数组中第5个元素,将桶中串接在buf数组并复制给nums,现在桶已经按个位排序 并个位相同先来先到,for(j=n-1;j--)求出每个数的个位num=(nums[j]/dev)%10并 放在buf合适位置buf[count[num]-1]=num[j]比如,21在51后面,所以逆序, 21放到buf[5-1]并count[1]--;向前遇到51放到buf[4-1]并count[1]--,这样就 buf就按个位排序,copy(buf.begin(),buf.end(),nums.begin())并place*=10处理 10位 class Solution { public: int maximumGap(vector<int>& nums) { int n=nums.size(); int maxNum=*max_element(nums.begin(),nums.end()); int maxBit=1,num=10; while(num<=maxNum){ maxBit++; num*=10; } vector<int>buf(n,0); for(int i=0,place=1;i<maxBit;i++,place*=10){ vector<int>count(10,0); for(int j=0;j<n;j++){ count[(nums[j]/place)%10]++; } for(int j=1;j<10;j++){ count[j]+=count[j-1]; } for(int j=n-1;j>=0;j--){ int num=(nums[j]/place)%10; buf[count[num]-1]=nums[j]; count[num]--; } copy(buf.begin(),buf.end(),nums.begin()); } int ans=0; for(int i=1;i<n;i++){ ans=max(ans,nums[i]-nums[i-1]); } return ans; } }; 桶排序 找到maxNum和minNum,计算桶个数bucketCnt,初始化vecBucket多个桶,每个桶初始化为 vector<int>,遍历nums[i],对应bucketIndex=(nums[i]-minNum)/bucketCnt,填入 clearnums,for每个bucketdfs快速排序,填入nums、 class Solution { public: int maximumGap(vector<int>& nums) { int n=nums.size(); int maxNum=*max_element(nums.begin(),nums.end()); int minNum=*min_element(nums.begin(),nums.end()); int bucketCnt=(maxNum-minNum)/n+1; vector<vector<int>>vecBucket; for(int i=0;i<bucketCnt;i++){ vector<int>vecTmp; vecBucket.push_back(vecTmp); } for(int i=0;i<n;i++){ int bucketIndex=(nums[i]-minNum)/bucketCnt; bucketIndex=bucketIndex>=bucketCnt?bucketCnt-1:bucketIndex; vecBucket[bucketIndex].push_back(nums[i]); } nums.clear(); for(auto bucket:vecBucket){ dfs(0,bucket.size()-1,bucket); for(int num:bucket)nums.push_back(num); } int ans=0; for(int i=1;i<n;i++){ ans=max(ans,nums[i]-nums[i-1]); } return ans; } void dfs(int beg,int end,vector<int>&nums){ if(beg>end)return; int i=beg,j=end; while(i<j){ while(nums[j]>=nums[beg]&&j>i)j--; while(nums[i]<=nums[beg]&&i<j)i++; if(i<j)swap(nums[i],nums[j]); } swap(nums[beg],nums[i]); dfs(beg,i-1,nums); dfs(i+1,end,nums); } };