315. Count of Smaller Numbers After Self

问题:

给定一个数组,从左向右遍历数组每一个元素,

对每一个元素,记录,其右边比他小的元素个数到res数组中。

求res数组。

Example:
Input: [5,2,6,1]
Output: [2,1,1,0] 
Explanation:
To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.

  

类似:493. Reverse Pairs

解法:

解法一:FenwickTree

使用以下辅助变量:

  • sortedNums:ftree,对给定数组,进行排序。
  • FenwickTree:sortnums,记录到目前为止,某个排序位置X以前,共有多少元素。(即<=X的元素有多少个)

由于本题,要求的是某元素以右的更小元素个数。

我们从后往前进行遍历,即可利用已经记录的结果。

最后将得到的res进行反转reverse即可。

代码参考:

 1 class FenwickTree {
 2 public:
 3     FenwickTree(int n):tree(n+1,0) {}
 4     void update(int i, int delta) {
 5         while(i<tree.size()){
 6             tree[i]+=delta;
 7             i+=lowbit(i);
 8         }
 9     }
10     int preSum(int i){
11         int sum=0;
12         while(i>0){
13             sum+=tree[i];
14             i-=lowbit(i);
15         }
16         return sum;
17     }
18 private:
19     vector<int> tree;
20     int lowbit(int x) {
21         return x&(-x);
22     }
23 };
24 class Solution {
25 public:
26     vector<int> countSmaller(vector<int>& nums) {
27         vector<int> res;
28         FenwickTree ftree(nums.size());
29         vector<int> sortnums(nums);
30         sort(sortnums.begin(), sortnums.end());
31         for(int i=nums.size()-1; i>=0; i--){
32             int pos = distance(sortnums.begin(), lower_bound(sortnums.begin(), sortnums.end(), nums[i]));
33             res.push_back(ftree.preSum(pos));
34             ftree.update(pos+1, 1);
35         }
36         reverse(res.begin(), res.end());
37         return res;
38     }
39 };

 

解法二:mergeSort

⚠️ 注意:由于mergeSort会打乱原来数组的顺序,在mergeSort过程中,要同时保存计数结果,

需要同时将原来的index位置,存入,使得在mergeSort的过程中,也能找到原来的位置,进行计数。

  • vector<vector<int>> numspos(nums.size(), vector<int>(2,0));

 

 1 class Solution {
 2 public:
 3     vector<int> countSmaller(vector<int>& nums) {
 4         vector<int> res(nums.size(), 0);
 5         vector<vector<int>> numspos(nums.size(), vector<int>(2,0));
 6         for(int i=0; i<nums.size(); i++){
 7             numspos[i][0]=nums[i];
 8             numspos[i][1]=i;
 9         }
10         mergeSort(numspos, res, 0, nums.size()-1);
11         return res;
12     }
13     void mergeSort(vector<vector<int>>& nums, vector<int>& res, int start, int end) {
14         if(end<=start) return;
15         int mid = start + (end - start) / 2;
16         mergeSort(nums, res, start, mid);
17         mergeSort(nums, res, mid+1, end);
18         merge(nums, res, start, mid, end);
19     }
20     void merge(vector<vector<int>>& nums, vector<int>& res, int start, int mid, int end) {
21         int p=start, q=mid+1, t=0;
22         vector<vector<int>> tmp(end-start+1, vector<int>(2,0));
23         for(p=start; p<=mid; p++){
24             while(q<=end && nums[p][0]>nums[q][0]){
25                 q++;
26             }
27             res[nums[p][1]]+=(q-1-mid);
28         }
29         p=start, q=mid+1;
30         while(p<=mid && q<=end){
31             if(nums[p][0]>nums[q][0]){
32                 tmp[t++]=nums[q++];
33             } else {
34                 tmp[t++]=nums[p++];
35             }
36         }
37         while(p<=mid){
38             tmp[t++]=nums[p++];
39         }
40         while(q<=end){
41             tmp[t++]=nums[q++];
42         }
43         copy(tmp.begin(), tmp.end(), nums.begin()+start);
44     }
45 };

 

posted @ 2020-08-03 17:21  habibah_chang  阅读(120)  评论(0编辑  收藏  举报