涉及知识点:
solution:
- 该题题意就是求每个数的逆序对的个数
- 求逆序对我们可以用归并排序或者前缀和来做
- 这里我们介绍前缀和的做法,归并排序求逆序对可以自行学习
- 我们倒着将数组的每一个数输入,然后求该数的前缀和,求完后该位置的数值+1
- 但是如果我们可以想到假如该值非常大,那么我们要用很大的数值去存,这样就会有很多无效的空间
- 所以我们还需要将所给的数进行离散化
std:
class Solution {
private:
vector<int> v;
vector<int> c;
int lowbit(int x)
{
return x&-x;
}
int sum(int x)
{
int res=0;
for (int i = x ; i ; i -= lowbit(i)) res += c[i];
return res;
}
void get(vector<int>& nums)
{
v.assign(nums.begin(),nums.end());
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
}
void add(int x,int m)
{
for(int i = x ; i < c.size() ; i += lowbit(i)) c[i] += m;
}
public:
vector<int> countSmaller(vector<int>& nums) {
vector<int> res;
int len = nums.size();
//离散化
get(nums);
//树状数组初始化
c.resize(len + 1);
for (int i = len-1; i >= 0; i -- )
{
int index = lower_bound(v.begin(),v.end(),nums[i]) - v.begin() + 1;
res.push_back(sum(index-1));
add(index,1);
}
reverse(res.begin(),res.end());
return res;
}
};