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

相关文章

SQL Server修改数据库名及物理数据文件名操作步骤

《SQLServer修改数据库名及物理数据文件名操作步骤》在SQLServer中重命名数据库是一个常见的操作,但需要确保用户具有足够的权限来执行此操作,:本文主要介绍SQLServer修改数据... 目录一、背景介绍二、操作步骤2.1 设置为单用户模式(断开连接)2.2 修改数据库名称2.3 查找逻辑文件名

MySQL JSON 查询中的对象与数组技巧及查询示例

《MySQLJSON查询中的对象与数组技巧及查询示例》MySQL中JSON对象和JSON数组查询的详细介绍及带有WHERE条件的查询示例,本文给大家介绍的非常详细,mysqljson查询示例相关知... 目录jsON 对象查询1. JSON_CONTAINS2. JSON_EXTRACT3. JSON_TA

Oracle修改端口号之后无法启动的解决方案

《Oracle修改端口号之后无法启动的解决方案》Oracle数据库更改端口后出现监听器无法启动的问题确实较为常见,但并非必然发生,这一问题通常源于​​配置错误或环境冲突​​,而非端口修改本身,以下是系... 目录一、问题根源分析​​​二、保姆级解决方案​​​​步骤1:修正监听器配置文件 (listener.

Linux中修改Apache HTTP Server(httpd)默认端口的完整指南

《Linux中修改ApacheHTTPServer(httpd)默认端口的完整指南》ApacheHTTPServer(简称httpd)是Linux系统中最常用的Web服务器之一,本文将详细介绍如何... 目录一、修改 httpd 默认端口的步骤1. 查找 httpd 配置文件路径2. 编辑配置文件3. 保存

Nginx 413修改上传文件大小限制的方法详解

《Nginx413修改上传文件大小限制的方法详解》在使用Nginx作为Web服务器时,有时会遇到客户端尝试上传大文件时返回​​413RequestEntityTooLarge​​... 目录1. 理解 ​​413 Request Entity Too Large​​ 错误2. 修改 Nginx 配置2.1

Java内存区域与内存溢出异常的详细探讨

《Java内存区域与内存溢出异常的详细探讨》:本文主要介绍Java内存区域与内存溢出异常的相关资料,分析异常原因并提供解决策略,如参数调整、代码优化等,帮助开发者排查内存问题,需要的朋友可以参考下... 目录一、引言二、Java 运行时数据区域(一)程序计数器(二)Java 虚拟机栈(三)本地方法栈(四)J

JAVA数组中五种常见排序方法整理汇总

《JAVA数组中五种常见排序方法整理汇总》本文给大家分享五种常用的Java数组排序方法整理,每种方法结合示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录前言:法一:Arrays.sort()法二:冒泡排序法三:选择排序法四:反转排序法五:直接插入排序前言:几种常用的Java数组排序

Python对PDF书签进行添加,修改提取和删除操作

《Python对PDF书签进行添加,修改提取和删除操作》PDF书签是PDF文件中的导航工具,通常包含一个标题和一个跳转位置,本教程将详细介绍如何使用Python对PDF文件中的书签进行操作... 目录简介使用工具python 向 PDF 添加书签添加书签添加嵌套书签Python 修改 PDF 书签Pytho

Java数组初始化的五种方式

《Java数组初始化的五种方式》数组是Java中最基础且常用的数据结构之一,其初始化方式多样且各具特点,本文详细讲解Java数组初始化的五种方式,分析其适用场景、优劣势对比及注意事项,帮助避免常见陷阱... 目录1. 静态初始化:简洁但固定代码示例核心特点适用场景注意事项2. 动态初始化:灵活但需手动管理代

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a