LeetCode 315 计算右侧小于当前元素的个数(树状数组)

这篇博客介绍了如何利用树状数组(又称为二叉索引树)来解决一个编程问题:给定一个整数数组,求每个元素右侧小于它的元素数量。文章详细解释了树状数组的基本概念、操作(如lowbit、add和query)以及在动态维护前缀和中的应用。通过示例代码展示了如何实现这个功能,特别提到了对于负数的处理技巧,即将所有数加一个较大的正数使其变为非负。
摘要由CSDN通过智能技术生成

题目描述
给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。

示例:
输入:nums = [5,2,6,1]
输出:[2,1,1,0]
解释:
5 的右侧有 2 个更小的元素 (2 和 1)
2 的右侧仅有 1 个更小的元素 (1)
6 的右侧有 1 个更小的元素 (1)
1 的右侧有 0 个更小的元素

树状数组视频链接
树状数组的作用:动态维护前缀和,前提是所有的数从1开始。树状数组tr[x] 保存的是以x为根节点的子树中叶节点的和。可以看下面的图,每一层末尾的零个数是相等的。tr[x]的长度为lowbit(x),还可以看出tr[x]的父节点是t[x+lowbit(x)],树的深度是log2n+1
在这里插入图片描述

基本操作lowbit(x):指的是非负整数n在二进制表示下最低位1以及后面0所构成的数字。例如:x = 10010,lowbit(x)=(10)2=2,lowbit(x)=x&(-x)
有两个操作:

  • add(x,k):为数字x加上k,由于树状数组是维护前缀和的,因此只要其中一个数字加上了k,那么后续的前缀数组也需要加k,但是在树状数组中只需要在 x, x+lowbit(x) …… 直到x < n 这几个位置上加上k即可。
    在这里插入图片描述
  • query(x):查询x的前缀和,只需要将 x ,x-lowbit(x) …… 直到x>0 为止,这些位置的和相加就是x的前缀和。
    在这里插入图片描述
    应用:
    单点修改以及区间查询;
    在这里插入图片描述区间修改,单点查询;
    在这里插入图片描述
    区间修改,区间查询。
    在这里插入图片描述
    对于本题目:树状数组下标存储的是数值,数组里面存储的是个数。从后向前遍历数组,查询query(x-1),也就是查询比x小的数的个数之和,然后修改树状数组x位置的值,因为x出现了一次,因此在x位置加1。注意由于数字的范围可能出现负数,不符合树状数组应用的条件,因此需要将每个数变成>=1的,在每一个数上加一个大的正数即可。
class Solution {
public:
    int n=20001;
    vector<int> tr;
    int lowbit(int x)
    {
        return x & -x;
    }
    void add(int x,int k)
    {       
        for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=k;      
    }
    int query(int x)
    {
        int res=0;
        for(int i=x;i;i-=lowbit(i)) res+=tr[i];
        return res;
    }
    vector<int> countSmaller(vector<int>& nums) {
        tr.resize(n+1);
        vector<int> res(nums.size());
        for(int i=nums.size()-1;i>=0;i--)
        {
            int x=nums[i]+10001;
            res[i]=query(x-1);
            add(x,1);
        }
        return res;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值