标签:个数 https code 元素 logs 链接 div 利用 lin
题目链接: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; } };
标签:个数 https code 元素 logs 链接 div 利用 lin
原文地址:https://www.cnblogs.com/qingjiuling/p/14052992.html