逆序对问题总结
背景
分析
Brute Force
vector< vector<int> > fun1(vector<int> nums){ vector< vector<int> > ans; int n=nums.size(); for(int i=0;i<n;i++){ for(int j=i+1;j<n;j++){ if(nums[j]<nums[i]){ ans.push_back({nums[i],nums[j]}); } } } return ans; }
BIT
int lowbit(int x){ return x&(-x); } int sum(int x,vector<int>& C){ int ans=0; while(x>0){ ans+=C[x]; x-=lowbit(x); } return ans; } void add(int x,int val, int Max, vector<int>& C){ while(x<=Max){ C[x]+=val; x+=lowbit(x); } } int fun2(vector<int> nums){ int n=nums.size(); unordered_map<int,int> mp; vector<int> temp(nums); sort(temp.begin(),temp.end()); int tot=1; for(auto i:temp){ mp[i]=tot++; } int ans=0; vector<int> C(tot+1,0); for(int i=n-1;i>=0;i--){ ans+=sum(mp[nums[i]]-1,C); add(mp[nums[i]],1,tot,C); } return ans; }
Merge sort
void merge(vector<int>& nums,int l, int mid,int r){ int n1=mid-l+1; int n2=r-mid; vector<int> L1; vector<int> L2; L1.assign(nums.begin()+l,nums.begin()+l+n1); L2.assign(nums.begin()+n1+l,nums.begin()+ n1+n2+l); int i1=0; int i2=0; while(i1<n1&&i2<n2){ if(L1[i1]<=L2[i2]){ nums[i1+i2+l]=L1[i1]; i1++; } else { nums[i1+i2+l]=L2[i2]; i2++; } } while(i1<n1){ nums[i1+i2+l]=L1[i1]; i1++; } while(i2<n2){ nums[i1+i2+l]=L2[i2]; i2++; } return; } int mergeSort(vector<int>& nums, int l, int r){ if(l>=r) return 0; int mid=(r+l)>>1; int ans=mergeSort(nums,l,mid)+mergeSort(nums,mid+1,r); int left=l; int right=mid+1; while(left<=mid){ while(right<=r&&nums[left]>nums[right]){ right++; } ans+=(right-mid-1); left++; } merge(nums,l,mid,r); return ans; } int fun3(vector<int> &nums){ return mergeSort(nums,0,nums.size()-1); }