Leetcode 315. Count of Smaller Numbers After Self

Problem:

You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i].

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.

 

Solution:

  这道题我看到的第一想法是模拟一个插入排序的过程。从右往左扫描,用vec数组保存已经从小到大排序好的数组,用二分法找到下一个元素应该插入的位置,将索引号保存并插入vec数组即可,虽然看似时间复杂度为O(nlogn),其实插入操作的时间复杂度为O(n),所以其实时间复杂度为O(n2)。

 1 class Solution {
 2 public:
 3     vector<int> countSmaller(vector<int>& nums) {
 4         vector<int> result(nums.size());
 5         if(nums.size() == 0) return result;
 6         vector<int> vec;
 7         for(int i = nums.size()-1;i >= 0;--i){
 8             int start = 0;
 9             int end = vec.size();
10             while(start < end){
11                 int pivot = start + (end-start)/2;
12                 if(nums[i] > vec[pivot])
13                     end = pivot;
14                 else
15                     start = pivot+1;
16             }
17             result[i] = vec.size()-start;
18             if(start == vec.size()) vec.push_back(nums[i]);
19             else vec.insert(vec.begin()+start,nums[i]);
20         }
21         return result;
22     }
23 };

  现在讲讲另一种用FenwickTree树状数组的解法,我们用一个rank数组记录数组中每个元素的rank,比如[5,2,6,1]的rank数组是[3,2,4,1],然后将rank数组逆序去更新一个FenwickTree树状数组,数组初始化为[0,0,0,0,0],在这个例子中的更新过程为:

  rank数组:[1,4,2,3]

  逆转数组:[1,6,2,5]

  1. [0,1,0,0,0]  //对于第一个数1,对应rank数组中的1,其左侧的和为0,所以result[4-0-1]=0

  2. [0,1,0,0,1]  //对于第二个数6,对应rank数组中的4,其左侧和为1,所以result[2]=1

  3. [0,1,1,0,1]  //对于第三个数2,对应rank数组中的2,其左侧和为1,所以result[1]=1

  4. [0,1,1,1,1]  //对于第四个数5,对应rank数组中的3,其左侧和为2,所以result[1]=2

Code:

 

 1 class FenwickTree{
 2 public:
 3     FenwickTree(int N){
 4         data = vector<int>(N+1);
 5         tree = vector<int>(N+1);
 6     }
 7     void update(int index){
 8         for(int i = index;i < tree.size();i+=lowBit(i))
 9             tree[i] += 1;
10         data[index]++;
11     }
12     int getSum(int last){
13         int result = 0;
14         for(int i = last;i > 0;i-=lowBit(i))
15             result += tree[i];
16         return result;
17     }
18 private:
19     int lowBit(int x){
20         return x&(-x);
21     }
22     vector<int> tree;
23     vector<int> data;
24 };
25 class Solution {
26 public:
27     vector<int> countSmaller(vector<int>& nums) {
28         set<int> s(nums.begin(),nums.end());
29         unordered_map<int,int> um;
30         int index = 0;
31         for(auto i:s){
32             um[i] = index;
33             index++;
34         }
35         vector<int> rank;
36         for(int i = nums.size()-1;i >= 0;--i)
37             rank.push_back(um[nums[i]]+1);
38         FenwickTree tree(s.size());
39         int m = nums.size();
40         vector<int> result(m);
41         for(int i = 0;i != rank.size();++i){
42             result[m-i-1] = tree.getSum(rank[i]-1);
43             tree.update(rank[i]);
44         }
45         return result;
46     }
47 };

 

posted on 2019-01-14 08:07  周浩炜  阅读(234)  评论(0编辑  收藏  举报

导航