题目

给你一个数组 nums ,请你完成两类查询。
其中一类查询要求 更新 数组 nums 下标对应的值
另一类查询要求返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 和 ,其中 left <= right
实现 NumArray 类:
NumArray(int[] nums) 用整数数组 nums 初始化对象
void update(int index, int val) 将 nums[index] 的值 更新 为 val
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 * 10^4
-100 <= nums[i] <= 100
0 <= index < nums.length
-100 <= val <= 100
0 <= left <= right < nums.length
调用 pdate 和 sumRange 方法次数不大于 3 * 10^4

来源:力扣(LeetCode)

解题思路

  这类题乍一看如果不考虑实际情况,假设一个理想的算力内存无限的情况下可以非常简单的直接写出来。

class NumArray:def __init__(self, nums: List[int]):self.nums=numsdef update(self, index: int, val: int) -> None:self.nums[index]=valdef sumRange(self, left: int, right: int) -> int:return sum(self.nums[left:right+1])# Your NumArray object will be instantiated and called as such:
# obj = NumArray(nums)
# obj.update(index,val)
# param_2 = obj.sumRange(left,right)

  但是这也的后果往往是超时的:

  一个简单的优化就是仿照分块查询来降低算法的时间复杂度,以一定的空间来换取时间。假设以分块来解决这样的题目,那么一个块内需要放多少元素呢?这个可以从时间复杂度的分析得出一个理论上的最优解,此题的初始化和更新值的操作需要的时间复杂度分别为O(n)和O(1),而求和的复杂度如果以上面的操作来算的话是O(left-right),也是O(n)的级别,所以每次求和十分耗费时间(因为初始化只需要一次,相对调用次数较少,无需考虑初始化的优化),分块的话假设一个块的大小为A,那么考虑一个最普通的情况right和left跨越三个块其时间复杂度就是O(A+n/A),当且仅当A取根号n的时候时间复杂度最小。

class NumArray:def __init__(self, nums: List[int]):self.blockSize=math.ceil(math.sqrt(len(nums)))self.sums=[0]*(len(nums)//self.blockSize+1)for i in range(len(nums)):self.sums[i//self.blockSize]+=nums[i]self.nums=numsdef update(self, index: int, val: int) -> None:self.sums[index//self.blockSize]+=val-self.nums[index]self.nums[index]=valdef sumRange(self, left: int, right: int) -> int:if left//self.blockSize==right//self.blockSize:return sum(self.nums[left:right+1])return sum(self.nums[left:(left//self.blockSize+1)*self.blockSize])+sum(self.sums[left//self.blockSize+1:right//self.blockSize])+sum(self.nums[right//self.blockSize*self.blockSize:right+1])# Your NumArray object will be instantiated and called as such:
# obj = NumArray(nums)
# obj.update(index,val)
# param_2 = obj.sumRange(left,right)

LeetCode中等题之区域和检索 - 数组可修改相关推荐

  1. LeetCode简单题之区域和检索 - 数组不可变

    题目 给定一个整数数组 nums,处理以下类型的多个查询: 计算索引 left 和 right (包含 left 和 right)之间的 nums 元素的 和 ,其中 left <= right ...

  2. C练题笔记之:Leetcode-307. 区域和检索 - 数组可修改

    题目: 给你一个数组 nums ,请你完成两类查询. 其中一类查询要求 更新 数组 nums 下标对应的值 另一类查询要求返回数组 nums 中索引 left 和索引 right 之间( 包含 )的n ...

  3. LeetCode中等题之二倍数对数组

    题目 给定一个长度为偶数的整数数组 arr,只有对 arr 进行重组后可以满足 "对于每个 0 <= i < len(arr) / 2,都有 arr[2 * i + 1] = 2 ...

  4. LeetCode(303)——区域和检索 - 数组不可变(JavaScript)

    给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点. 示例1: 给定 nums = [-2, 0, 3, -5, 2, -1],求和函数为 ...

  5. 307. Range Sum Query - Mutable | 307. 区域和检索 - 数组可修改(数据结构:线段树,图文详解)

    题目 https://leetcode.com/problems/range-sum-query-mutable/ 吐槽官方题解 这题的 英文版官方题解,配图和代码不一致,而且描述不清:力扣国内版题解 ...

  6. LeetCode 303. 区域和检索 - 数组不可变(前缀和)

    1. 题目 给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点. 示例: 给定 nums = [-2, 0, 3, -5, 2, -1],求 ...

  7. leetcode - 303.区域和检索-数组不可变(动态规划)

    303.区域和检索-数组不可变 ------------------------------------------ 给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素 ...

  8. leetcode 303. 区域和检索 - 数组不可变(Java版)

    题目 303. 区域和检索 - 数组不可变 题解 经典的累加和问题. 定义一个数组 sum,存放数组从 0 到 sum 的累加和. 欲求某区间的累加和,只需将对应位置 sum 相减即可. 时间复杂度O ...

  9. LeetCode 308. 二维区域和检索 - 可变(前缀和)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个 2D 矩阵 matrix,请计算出从左上角 (row1, col1) 到右下角 (row2, col2) 组成的矩形中所有元素的和. 上述粉色矩 ...

最新文章

  1. oracle数据导出方法,oracle多种导入导出数据方法
  2. C++中的大小转换函数和翻转函数
  3. 调查问卷 | 中国云原生用户调研,邀您参与!
  4. Spring--@within和@target的区别
  5. 英特尔ARM开启芯片之战 消费者该何去何从?
  6. fl如何保存再次打开_「Excel技巧」Excel2016如何将自己设计的图表存为模板反复使用?...
  7. C++学习笔记-windows底层粗略认识
  8. .net core精彩实例分享 -- LINQ
  9. c语言割线法解非线性方程,用割线法解非线性方程组.doc
  10. 纸巾,理由最充分的涨价
  11. [SDOI2013]直径
  12. C#DataGridView中的常用技巧
  13. C 数据结构与算法 散列表
  14. Centos6.5 源码安装MySql5.6.33
  15. Uabntu安装AWVS11以及破解
  16. python 组态_西门子组态WinCC自学入门视频教程资源_48讲
  17. [统计学理论基础] 置信区间
  18. Fusion APP-检查软件更新-远程公告
  19. R语言ggplot2可视化在轴标签中添加上标(Superscript)和下标(subscript)实战
  20. 使用 NGINX 搭建 RTMP 流媒体服务器实现直播功能

热门文章

  1. 伍六七带你学算法 入门篇——最后一个单词的长度
  2. 2022-2028年中国汽车修理行业市场前瞻与投资规划分析报告
  3. 广东java工资一般多少_广东java工资待遇,广东java工资一般多少,广东java工资底薪最低多少...
  4. python对文件的读写正确操作方式
  5. IntelliJ IDEA中用快捷键自动创建测试类
  6. xshell问题汇总
  7. 矩阵乘以其矩阵转置求导-数学
  8. 带你彻彻底底搞懂朴素贝叶斯公式
  9. 【图论】有向无环图的拓扑排序
  10. 现代传感器的接口:中断驱动的ADC驱动程序