面试题51. 数组中的逆序对
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
题目链接
思路
运用树状数组解决问题。为了让数据的表示范围合理,还要进行离散化。
代码
这道题最坑的地方在于有可能数组中有重复的数字,例如[1,3,2,1,2],所以一定要去重,然后再离散化。根据离散化后的下标的顺序来插入树状数组,重新统计结果。
class Solution {
public:
lowbit(int x){
return (x & -x);
}
int query(int tar,vector<int> &c){
int ans = 0;
while(tar > 0){
ans += c[tar];
tar -= lowbit(tar);
}
return ans;
}
void update(int tar,int l,vector<int> &c){
while(tar <= l){
c[tar]++;
tar += lowbit(tar);
}
}
int reversePairs(vector<int>& nums) {
vector<int> c(nums.size() + 10,0);
int l = nums.size(),ans = 0;
vector<int> temp(nums);
//排序
sort(temp.begin(),temp.end());
//去重!!!
temp.erase(unique(temp.begin(),temp.end()),temp.end());
map<int,int> arr;
for(int i = 0;i < temp.size();i++){
arr.insert(pair<int,int>(temp[i],i + 1));
}
//更新
for(int i = 1;i <= l;i++){
int tar = arr[nums[i - 1]];
update(tar,l,c);
ans += i - query(tar,c);
}
return ans;
}
};