1. 程式人生 > >Leetcode 315. Count of Smaller Numbers After Self

Leetcode 315. Count of Smaller Numbers After Self

個數 初始 tor ktr href number .get numbers cto

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 };

Leetcode 315. Count of Smaller Numbers After Self