307区域和检索 - 数组可修改(线段树)

2023-10-04 21:10

本文主要是介绍307区域和检索 - 数组可修改(线段树),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、题目描述

给定一个整数数组  nums,求出数组从索引 i 到 j  (i ≤ j) 范围内元素的总和,包含 i,  j 两点。

update(i, val) 函数可以通过将下标为 i 的数值更新为 val,从而对数列进行修改。

说明:

  • 数组仅可以在 update 函数下进行修改。
  • 你可以假设 update 函数与 sumRange 函数的调用次数是均匀分布的。

2、示例

Given nums = [1, 3, 5]sumRange(0, 2) -> 9
update(1, 2)
sumRange(0, 2) -> 8

3、题解

基本思想:线段树

  • 建立线段树:将nums值放入tree最后面作为叶子节点,然后不断更新父节点等于子节点值之和tree[i]=tree[2*i]+tree[2*i+1]
  • 更新线段树:将叶子节点及其往上的节点直到根节点都要更新,时间复杂度O(logn)
  • 查找检索线段树:如果左边界是右子节点,将该节点加入到sum否则往上查找其父节点值,如果右边界是左子节点,将该节点加入到sum否则往上查找其父节点值,这样不断往上查找直到左右边界相遇,时间复杂度O(logn)
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
class NumArray {
public:NumArray(vector<int>& nums) {if(nums.size()==0)  return;sum.resize(nums.size());sum[0]=nums[0];for(int i=1;i<nums.size();i++)sum[i]=sum[i-1]+nums[i];}void update(int i, int val) {int diffval=i==0?val-sum[i]:val-(sum[i]-sum[i-1]);if(diffval==0)  return;for(int j=i;j<sum.size();j++)sum[j]+=diffval;}int sumRange(int i, int j) {return i==0?sum[j]:sum[j]-sum[i-1];}
private:vector<int> sum;
};
class NumArray1 {
public:NumArray1(vector<int>& nums) {//建立线段树:将nums值放入tree最后面作为叶子节点,然后不断更新父节点等于子节点值之和tree[i]=tree[2*i]+tree[2*i+1]if(nums.size()==0)  return;n=nums.size();tree.resize(2*n);for(int i=0,j=n;i<nums.size();i++,j++)tree[j]=nums[i];for(int i=n-1;i>0;i--)tree[i]=tree[2*i]+tree[2*i+1];}void update(int i, int val) {//更新线段树:将叶子节点及其往上的节点直到根节点都要更新,时间复杂度O(logn)int pos=i+n;int diffval=val-tree[pos];if(diffval==0)  return;while(pos>0){tree[pos]+=diffval;pos/=2;}}int sumRange(int i, int j) {//查找检索线段树:如果左边界是右子节点,将该节点加入到sum否则往上查找其父节点值,//如果右边界是左子节点,将该节点加入到sum否则往上查找其父节点值,这样不断往上查找直到左右边界相遇,时间复杂度O(logn)int sum=0;i+=n;j+=n;while(i<=j){//如果左边界是右子节点,将该节点加入到sum这样避免误加左子节点值if(i%2==1){sum+=tree[i];i++;}//如果右边界是左子节点,将该节点加入到sum这样避免误加右子节点值if(j%2==0){sum+=tree[j];j--;}//之后就更新边界到其父节点通过加其父节点值就加了两个子节点值,这样时间复杂度只有O(logn)i/=2;j/=2;}return sum;}
private:vector<int> tree;int n;
};
int main()
{vector<int> nums={1,3,5};NumArray1* obj = new NumArray1(nums);cout<<obj->sumRange(0,2)<<endl;obj->update(1,2);cout<<obj->sumRange(0,2)<<endl;return 0;
}

 

这篇关于307区域和检索 - 数组可修改(线段树)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/2729

相关文章

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

kingbase修改权限实现方式

《kingbase修改权限实现方式》该文章详细介绍了如何在数据库中创建用户并赋予其相应的权限,包括创建用户、回收默认权限、创建数据库、赋权数据库权限、创建只读用户以及回收权限等步骤... 目录前言使用步骤总结前言创建用户后对数据库对象的读写权限进行修改使用步骤1、创建用户create user cs

linux实现对.jar文件的配置文件进行修改

《linux实现对.jar文件的配置文件进行修改》文章讲述了如何使用Linux系统修改.jar文件的配置文件,包括进入文件夹、编辑文件、保存并退出编辑器,以及重新启动项目... 目录linux对.jar文件的配置文件进行修改第一步第二步 第三步第四步总结linux对.jar文件的配置文件进行修改第一步进

Python实现Word文档自动化的操作大全(批量生成、模板填充与内容修改)

《Python实现Word文档自动化的操作大全(批量生成、模板填充与内容修改)》在职场中,Word文档是公认的好伙伴,但你有没有被它折磨过?批量生成合同、制作报告以及发放证书/通知等等,这些重复、低效... 目录重复性文档制作,手动填充模板,效率低下还易错1.python-docx入门:Word文档的“瑞士

JavaScript对象转数组的三种方法实现

《JavaScript对象转数组的三种方法实现》本文介绍了在JavaScript中将对象转换为数组的三种实用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录方法1:使用Object.keys()和Array.map()方法2:使用Object.entr

Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧

《Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧》本文将通过实际代码示例,深入讲解Python函数的基本用法、返回值特性、全局变量修改以及异常处理技巧,感兴趣的朋友跟随小编一起看看... 目录一、python函数定义与调用1.1 基本函数定义1.2 函数调用二、函数返回值详解2.1 有返

Nginx屏蔽服务器名称与版本信息方式(源码级修改)

《Nginx屏蔽服务器名称与版本信息方式(源码级修改)》本文详解如何通过源码修改Nginx1.25.4,移除Server响应头中的服务类型和版本信息,以增强安全性,需重新配置、编译、安装,升级时需重复... 目录一、背景与目的二、适用版本三、操作步骤修改源码文件四、后续操作提示五、注意事项六、总结一、背景与

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

Java中数组与栈和堆之间的关系说明

《Java中数组与栈和堆之间的关系说明》文章讲解了Java数组的初始化方式、内存存储机制、引用传递特性及遍历、排序、拷贝技巧,强调引用数据类型方法调用时形参可能修改实参,但需注意引用指向单一对象的特性... 目录Java中数组与栈和堆的关系遍历数组接下来是一些编程小技巧总结Java中数组与栈和堆的关系关于

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问