IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 区域和检索 - 数组可修改 -> 正文阅读

[数据结构与算法]区域和检索 - 数组可修改

一、区域和检索 - 数组可修改

1.1、题设要求

给你一个数组 nums ,请你完成两类查询。

  1. 其中一类查询要求更新数组 nums 下标对应的值;
  2. 另一类查询要求返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的和 ,其中 left <= right

实现 NumArray 类:

  1. NumArray(int[] nums) 用整数数组 nums 初始化对象;
  2. void update(int index, int val) 将 nums[index] 的值 更新 为 val;
  3. int sumRange(int left, int right) 返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的和 (即,nums[left] + nums[left + 1], …, nums[right])。
示例 1:
输入:
["NumArray", "sumRange", "update", "sumRange"]
[[[1, 3, 5]], [0, 2], [1, 2], [0, 2]]
输出:
[null, 9, null, 8]

解释:
NumArray numArray = new NumArray([1, 3, 5]);
numArray.sumRange(0, 2); // 返回 1 + 3 + 5 = 9
numArray.update(1, 2);   // nums = [1,2,5]
numArray.sumRange(0, 2); // 返回 1 + 2 + 5 = 8

提示:
1 <= nums.length <= 3 * 104
-100 <= nums[i] <= 100
0 <= index < nums.length
-100 <= val <= 100
0 <= left <= right < nums.length
调用 pdate 和 sumRange 方法次数不大于 3 * 104 

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/range-sum-query-mutable

1.2、lowbit()操作

??要先搞这个算法,就要先搞懂树状数组是什么东西。

??想要了解树状数组,有个前置知识是必须知道的,那就是**lowbit()**运算。何为lowbit()运算呢,它的概念性理解就是非负整数在二进制表示下最低位及其后面的0构成的数值,简单来讲就是lowbit(n)中的n与其负数(补码(取反加1))的按位与。

请添加图片描述

//计算树状数组中的lowbit(x)的值
int lowbit(int x){
    return x & -x;
}

1.3、思想与实现

c[x]是[x-lowbit(x)+1,x]的求和,现在我们画出下面序列的图。

请添加图片描述

C[x]的父亲节点是C[x+lowbit(x)]

1.4、query方法与add方法

1.4.1、query方法(区间查询)

C[x]进行更加或增加,只需修改并改变祖先节点,将 x += lowbit(x) 计算出来,就可以得到父节点的下标。

//树状数组中的query方法
int query(int x){
    int ans = 0;
    //查询tree[x]节点的前缀
    for(int i = x;i > 0;i -= lowbit(i))
        //计算tree[x]节点的前缀和
        ans += tree[i];
    return ans;
}

1.4.2、add方法(单点修改)

查询C[x]节点的前缀和,从该节点向座上找到上一个节点,将 x -= lowbit(x) 计算出来,就可以得到上一个节点的下标。

//树状数组中的add方法
void add(int x,int y){
    //查询tree[x]节点的祖先节点
    for(int i = x;i <= n;i +=lowbit(i))
        //将tree[x]节点的祖先节点进行更改
        tree[i] += y;
}

1.5、解题思路

因为题目要求实现更新nuns在某个位置的值,因此我们保存原始的nums数组。

  1. 构造函数:树状数组初始对应一个零序列,因此我们遍历nums数组,调用add函数来更新树状数组。
  2. update 函数:获取nums在index的增加值,调用add函数更新树状数组,并更新 nums[index] = val。
  3. sumRange函数:区间和[left,right]可以转化为两个前缀和之差,调用树状数组的 prefixSum函数获取前 right + 1 个元素的前缀和sum1和前left个元素的前缀和sum2,返回sum1 - sum2。

1.6、算法

class NumArray {
    //定义一个树状数组
    int [] tree;
    int [] sum;
    int n;

    //计算树状数组中的lowbit(x)的值
    int lowbit(int x){
        return x & -x;
    }

    //树状数组中的query方法
    int query(int x){
        int ans = 0;
        //查询tree[x]节点的前缀
        for(int i = x;i > 0;i -= lowbit(i))
            //计算tree[x]节点的前缀和
            ans += tree[i];
        return ans;
    }

    //树状数组中的add方法
    void add(int x,int y){
        //查询tree[x]节点的祖先节点
        for(int i = x;i <= n;i +=lowbit(i))
            //将tree[x]节点的祖先节点进行更改
            tree[i] += y;
    }

    //用整数数组 nums 初始化对象
    public NumArray(int[] nums) {
        sum = nums;
        n = sum.length;
        tree = new int[n+1];
        for(int i = 0;i<n;i++)
            add(i + 1,sum[i]);
    }
    
    //将 nums[index] 的值 更新 为 val
    public void update(int index, int val) {
        add(index + 1,val-sum[index]);
        sum[index] = val;
    }
    
    //返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的和
    public int sumRange(int left, int right) {
        return query(right + 1) - query(left);
    }
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-06 23:27:37  更:2022-04-06 23:27:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:03:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码