赞
踩
给定一个整型数组 nums
,按要求返回一个新的 counts
数组。数组 counts
有该性质: counts[i]
的值是 nums[i]
右侧小于nums[i]
的元素的数量。
例子:
返回数组 [2, 1, 1, 0]
.
用树状数组(lowbit
),然后倒序遍历原始数组即可
class Solution {
public:
int lowbit(int x){
return (int)x&(-1*x);
}
int getSum(int x,vector<int> &c){
int sum=0;
for(int i=x;i>0;i-=lowbit(i)){
sum+=c[i];
}
return sum;
}
void update(vector<int> &c,int x,int v){
for(int i=x;i<c.size();i+=lowbit(i)){
c[i]+=v;
}
}
vector<int> countSmaller(vector<int>& nums) {
vector<int> count;
set<int> ss;
for(auto t:nums){
ss.insert(t);
}
unordered_map<int,int> m;
int n=ss.size();
auto it=ss.begin();
for(int i=1;i<=n;i++){
m[*it]=i;
it++;
}
vector<int> sum(n+1,0);
for(auto it=nums.rbegin();it!=nums.rend();it++){
int res=0;
int idx=m[*it];
if(idx>1){
res=getSum(idx-1,sum);
}
update(sum,m[*it],1);
count.push_back(res);
}
reverse(count.begin(),count.end());
return count;
}
};
考虑用一个数组tmp
有序保存已经遍历过的数字,那么对于一个nums
中一个元素,需要知道它右侧小于它的元素的个数,即它在tmp
中插入的位置,即可计算出右侧小于它的元素个数,对于它在tmp
中的位置可以直接用二分法查找,比如用lower_bound
class Solution {
public:
vector<int> countSmaller(vector<int>& nums) {
int n=nums.size();
vector<int> res(n,0),tmp;
for(int i=n-1;i>=0;i--){
auto it=lower_bound(tmp.begin(),tmp.end(),nums[i]);
res[i]=it-tmp.begin();
tmp.insert(it,nums[i]);
}
return res;
}
};
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。