Leetcode 493. Reverse Pairs

Problem:

Given an array nums, we call (i, j) an important reverse pair if i < j and nums[i] > 2*nums[j].

You need to return the number of important reverse pairs in the given array.

Example1:

Input: [1,3,2,3,1]
Output: 2

Example2:

Input: [2,4,3,5,1]
Output: 3

Note:

  1. The length of the given array will not exceed 50,000.
  2. All the numbers in the input array are in the range of 32-bit integer.

Solution:

  这道题再用类似Leetcode 315. Count of Smaller Numbers After Self中的插入排序方法就只能打擦边球AC了,类似的,这道题应该要想到用FenwickTree树状数组来解决。我们用一个集合s存储所有不重复的数字,然后用一个sorted数组存储排序后的唯一的数字,用一个哈希表记录了唯一的数字对应的rank值,并维护了一个FenwickTree,用rank数组对所有数字进行一个排名。和Leetcode 315类似,我们需要在这个树状数组中寻找前x个数之和,不同的是,Leetcode 315的处理比较简单,这里的x是比nums[i]/2.0小的最大值,我们可以利用这个sorted数组进行二分查找。然后不断更新这个树状数组即可。时间复杂度是O(nlogn)

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 
26 class Solution {
27 public:
28     int reversePairs(vector<int>& nums) {
29         set<int> s(nums.begin(),nums.end());
30         vector<int> sorted(s.begin(),s.end());
31         unordered_map<int,int> um;
32         int index = 1;
33         for(auto i:s){
34             um[i] = index;
35             index++;
36         }
37         int m = nums.size();
38         vector<int> rank(m);
39         for(int i = 0;i != nums.size();++i)
40             rank[i] = um[nums[i]];
41         int result = 0;
42         FenwickTree tree(s.size());
43         for(int i = m-1;i >= 0;--i){
44             double target = nums[i]/2.0;
45             if(target <= sorted[0]) {
46                 tree.update(rank[i]);
47                 continue;
48             }
49             int start = 0;
50             int end = sorted.size()-1;
51             while(start < end){
52                 int pivot = start+(end-start+1)/2;
53                 if(sorted[pivot] >= target)
54                     end = pivot-1;
55                 else
56                     start = pivot;
57             }
58             result += tree.getSum(um[sorted[start]]);
59             tree.update(rank[i]);
60         }
61         return result;
62     }
63 };

 

posted on 2019-01-14 12:36  周浩炜  阅读(239)  评论(0编辑  收藏  举报

导航