收获
lower_bound的使用,lower_bound()是采用二分查找,时间复杂度为O(log(n))
要求nums数组是一个有序数组
lower_bound(nums.begin(),nums.end(),num)返回一个地址
lower_bound查找不小于目标值的第一个元素。
也就是说,使用该函数在指定范围内查找某个目标值时,
最终查找到的不一定是和目标值相等的元素,还可能是比目标值大的元素。
lower_bound(nums.begin(),nums.end(),num)-nums.begin()+1,返回相应下标,从1开始
- 离散化树状数组
- 巩固树状数组
难度:困难
题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例
输入: [7,5,6,4]
输出: 5
限制: 0 <= 数组长度 <= 50000
解题思路
- 典型的树状数组题,且要采用离散化,动态维护前缀关系
- 离散化思路:
(1)将数组内元素定位到排序后的下标
nums:[7,5,6,4]
排序后:[4,5,6,7]
nums对应下标:[4,2,3,1]
- 剩下的就是树状数组模板题套用
相关解题代码
class Solution {
public:
vector<int>tree;
int n;
int lowbit(int x){return x&(-x);}
int querty(int x){
int res=0;
while(x){
res+=tree[x];
x-=lowbit(x);
}
return res;
}
void update(int x){
while(x<=n){
++tree[x];
x+=lowbit(x);
}
}
int reversePairs(vector<int>& nums) {
n=nums.size();tree.resize(n+1);
/**
离散化树状数组
***/
vector<int>temp=nums;sort(temp.begin(),temp.end());
for(int &num : nums){
num=lower_bound(temp.begin(),temp.end(),num)-temp.begin()+1;
}
/**
树状数组查询,更新
**/
int ans=0;
for(int i=n-1;i>=0;i--){
ans+=querty(nums[i]-1);
update(nums[i]);
}
return ans;
}
};