LeetCode307. 区域和检索 - 数组可修改(树状数组、线段树)

本文介绍了树状数组(Binary Indexed Tree)这一数据结构,并通过讲解LeetCode上的‘范围更新查询’问题来阐述其在动态更新和查询前缀和上的高效性能。通过代码实现详细解析了树状数组的构造、单点修改和区间查询方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、树状数组

树状数组专题:https://leetcode-cn.com/tag/binary-indexed-tree/problemset/
视频:https://www.bilibili.com/video/BV1LW411e7jo?spm_id_from=333.337.search-card.all.click
在这里插入图片描述

2、题目描述

https://leetcode-cn.com/problems/range-sum-query-mutable/
在这里插入图片描述
在这里插入图片描述

3、代码详解

https://leetcode-cn.com/problems/range-sum-query-mutable/solution/qu-yu-he-jian-suo-shu-zu-ke-xiu-gai-by-l-76xj/
在这里插入图片描述

class NumArray {
    private int[] nums;  // 题目要求实现更新 nums 在某个位置的值,因此保存原始的 nums 数组

    private int[] tree;
    private int lowBit(int x) {
        return x & -x;
    }

    // 单点修改: 在树状数组 index 位置中增加值 val
    private void add(int index, int val) {
        while (index < tree.length) {
            tree[index] += val;
            index += lowBit(index);
        }
    }

    // 区间查询:查询前 index 个元素的前缀和
    private int prefixSum(int index) {
        int sum = 0;
        while (index > 0) {
            sum += tree[index];
            index -= lowBit(index);
        }
        return sum;
    }

    //————————————————————————————————
    // 构造函数
    public NumArray(int[] nums) {
        this.tree = new int[nums.length + 1];
        this.nums = nums;
        for (int i = 0; i < nums.length; i++) {
            // 树状数组是一种可以动态维护序列前缀和的数据结构(序列下标从 1 开始)
            add(i + 1, nums[i]);
        }
    }

    // 更新 数组 nums 下标对应的值: 将 nums[index] 的值 更新 为 val
    public void update(int index, int val) {
        add(index + 1, val - nums[index]);
        nums[index] = val;
    }

    // 返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 和
    public int sumRange(int left, int right) {
        return prefixSum(right + 1) - prefixSum(left);
    }

}



/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray obj = new NumArray(nums);
 * obj.update(index,val);
 * int param_2 = obj.sumRange(left,right);
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值