归并排序
参考剑指 Offer 51. 数组中的逆序对 - 力扣(LeetCode) (leetcode-cn.com)
重点是被排序过程中的数字下标的对应,这里取了一个index数列,在排序的同时进行移动,从而保证下标对应
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| class Solution { public: vector<int> countSmaller(vector<int>& nums) { int n = nums.size(); tmp.resize(n); index.resize(n); indextmp.resize(n); ret.resize(n); for(int i = 0; i < n; ++i) index[i] = i; mergeSort(nums, 0, n - 1); return ret; } private: vector<int> ret; vector<int> tmp; vector<int> index; vector<int> indextmp; void mergeSort(vector<int>& nums, int lo, int hi) { if(lo >= hi) return; int mid = lo + (hi - lo) / 2; mergeSort(nums, lo, mid); mergeSort(nums, mid + 1, hi); copy(nums.begin() + lo, nums.begin() + hi + 1, tmp.begin() + lo); copy(index.begin() + lo, index.begin() + hi + 1, indextmp.begin() + lo); int i = lo, j = mid + 1, k = lo; while(k <= hi) { if(i == mid + 1) { nums[k] = tmp[j]; index[k] = indextmp[j++]; }else if(j == hi + 1) { ret[indextmp[i]] += j - mid - 1; nums[k] = tmp[i]; index[k] = indextmp[i++]; } else if(tmp[i] <= tmp[j]) { ret[indextmp[i]] += j - mid - 1; nums[k] = tmp[i]; index[k] = indextmp[i++]; }else { nums[k] = tmp[j]; index[k] = indextmp[j++]; } ++k; } } };
|
离散化树状数组
迟点看 https://www.cnblogs.com/xenny/p/9739600.html
https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/solution/shu-zhuang-shu-zu-by-liweiwei1419/