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:
- The length of the given array will not exceed
50,000
. - 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 };