20.11.28 leetcode493翻轉對
阿新 • • 發佈:2020-11-28
題目連結:https://leetcode-cn.com/problems/reverse-pairs/
題意:給你一個數組,求滿足i<j且nums[i]>2*num[j]的(i,j)對的數量
分析:本質上,就是對陣列中的每一個元素,統計位於它左側或右側,且取值位於某個區間內的值的數量,和leetcode327統計區間和個數基本一樣。我這次還是用歸併做的,然後我把樹狀陣列的程式碼也貼一下。
歸併
class Solution { public: int recursive(vector<int>& nums,int left,int right){if(left==right)return 0; int mid=(left+right)/2; int res1=recursive(nums,left,mid); int res2=recursive(nums,mid+1,right); int res=res1+res2; int i=left,j=mid+1; while(i<=mid){ while(j<=right&&(long long)nums[i]>2*(long long)nums[j])j++; res+=(j-mid-1); i++; } vector<int> sorted; i=left,j=mid+1; while(i<=mid&&j<=right){ if(nums[i]<=nums[j]){ sorted.push_back(nums[i]); i++; }else{ sorted.push_back(nums[j]); j++; } } while(i<=mid){ sorted.push_back(nums[i]); i++; } while(j<=right){ sorted.push_back(nums[j]); j++; } for(int i=0;i<sorted.size();i++){ //cout<<sorted[i]<<" "; nums[left+i]=sorted[i]; } // cout<<endl; return res; } int reversePairs(vector<int>& nums) { if(nums.size()==0)return 0; return recursive(nums,0,nums.size()-1); } };
樹狀陣列:
class BIT { private: vector<int> tree; int n; public: BIT(int _n) : n(_n), tree(_n + 1) {} static constexpr int lowbit(int x) { return x & (-x); } void update(int x, int d) { while (x <= n) { tree[x] += d; x += lowbit(x); } } int query(int x) const { int ans = 0; while (x) { ans += tree[x]; x -= lowbit(x); } return ans; } }; class Solution { public: int reversePairs(vector<int>& nums) { set<long long> allNumbers; for (int x : nums) { allNumbers.insert(x); allNumbers.insert((long long)x * 2); } // 利用雜湊表進行離散化 unordered_map<long long, int> values; int idx = 0; for (long long x : allNumbers) { values[x] = ++idx; } int ret = 0; BIT bit(values.size()); for (int i = 0; i < nums.size(); i++) { int left = values[(long long)nums[i] * 2], right = values.size(); ret += bit.query(right) - bit.query(left); bit.update(values[nums[i]], 1); } return ret; } };