LeetCode(307) Range Sum Query - Mutable
题目
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive.
The update(i, val) function modifies nums by updating the element at index i to val.
Example:
Given nums = [1, 3, 5]
sumRange(0, 2) -> 9
update(1, 2)
sumRange(0, 2) -> 8
Note:
The array is only modifiable by the update function.
You may assume the number of calls to update and sumRange function is distributed evenly.
分析
一个可变数组数据结构的实现,包含更新数组元素和求部分和两个函数。
乍一看好像一个很简单的题目,很容易便可以 根据下标O(1)更新元素,由遍历操作O(n)实现求和;但是得到TLE的提交反馈也应该在意料之中。
查阅资料,发现一个树状数组的解法,给出参考博客:网址
树状数组是一种用于通过辅助数组和位置算法实现动态管理部分和的一种算法,其核心函数为lowbit、add、sum,当我们需要加入一个元素时,使用add函数向某个位置注入值,当需要求0~某位置的和时,调用sum函数传入这个位置即可:
int lowbit(int pos){
return pos&(-pos);
}
void add(int pos, int value){
while(pos < c.size()){
c[pos] += value;
pos += lowbit(pos);
}
}
int sum(int pos){
int res = 0;
while(pos > 0){
res += c[pos];
pos -= lowbit(pos);
}
return res;
}
其中c就是辅助数组。需要注意的是树状数组的索引必须从1开始,因此在与题目的输入量相转化时,需要把索引+1作为树状数组的索引。
假设我们有数组arr:{1,2,3},要求部分和,我们先把这些值通过add注入树状数组,一定要注意索引+1.
for(int i = 0; i < 3; i++){
add(i+1,arr[i]); // 把arr[i]添加到树状数组的i+1位置
}
操作完成后,树状数组就建立好了,下面就可以利用sum来求和了。例如我们需要arr中索引0~2的和,那么使用sum(3)即可,如果要求1~2的和,可以用sum(3)-sum(0),注意到,sum(0)对于树状数组是一个非法索引,但是通过观察sum函数发现pos=0正好返回0,也就是到这个位置的和为0,满足要求,不必特殊处理。
综上所述,要求arr中i~j的部分和,使用sum(j+1)-sum(i)即可。
值的更新问题,题目要求使用update函数更新arr中位置i的值为val,这就要利用add函数来实现,注意add函数是在位置pos上追加一个值value,而不是覆盖,因此我们需要计算值的变化量,把它追加到相应位置,并且一定要记得更新arr,否则下次得到的变化量是错误的。
void update(int i, int val) {
int ori = m_nums[i]; // m_nums是拷贝arr数组所得的成员变量
int delta = val - ori;
m_nums[i] = val;
add(i+1,delta);
}
所谓树状数组也是第一次了解到,还需查阅资料深入学习一下。
AC代码
//普通方法实现
class NumArray1 {
public:
NumArray1(vector<int> &nums) {
array = vector<int>(nums.begin(), nums.end());
int len = array.size(), tmpSum = 0;
for (int i = 0; i < len; ++i)
{
tmpSum += array[i];
allSum.push_back(tmpSum);
}//for
}
void update(int i, int val) {
if (i < 0 || i >= array.size())
return;
int tmp = val - array[i];
array[i] = val;
for (; i < array.size(); ++i)
allSum[i] += tmp;
}
int sumRange(int i, int j) {
if (i < 0 || i >= array.size() || j<0 || j >= array.size() || i>j)
return 0;
if (0 == i)
return allSum[j];
else
return allSum[j] - allSum[i - 1];
}
private:
vector<int> array;
vector<int> allSum;
};
//树状数组实现
class NumArray {
private:
vector<int> c;
vector<int> m_nums;
public:
NumArray(vector<int> &nums) {
c.resize(nums.size() + 1);
m_nums = nums;
for (int i = 0; i < nums.size(); i++){
add(i + 1, nums[i]);
}
}
int lowbit(int pos){
return pos&(-pos);
}
void add(int pos, int value){
while (pos < c.size()){
c[pos] += value;
pos += lowbit(pos);
}
}
int sum(int pos){
int res = 0;
while (pos > 0){
res += c[pos];
pos -= lowbit(pos);
}
return res;
}
void update(int i, int val) {
int ori = m_nums[i];
int delta = val - ori;
m_nums[i] = val;
add(i + 1, delta);
}
int sumRange(int i, int j) {
return sum(j + 1) - sum(i);
}
};
LeetCode(307) Range Sum Query - Mutable的更多相关文章
- LeetCode(304)Range Sum Query 2D - Immutable
题目 Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper ...
- LeetCode(303)Range Sum Query - Immutable
题目 Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclus ...
- 【刷题-LeetCode】307. Range Sum Query - Mutable
Range Sum Query - Mutable Given an integer array nums, find the sum of the elements between indices ...
- [Leetcode Week16]Range Sum Query - Mutable
Range Sum Query - Mutable 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/range-sum-query-mutable/de ...
- LeetCode(113) Path Sum II
题目 Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given ...
- [LeetCode] 307. Range Sum Query - Mutable 区域和检索 - 可变
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...
- [LeetCode] Range Sum Query - Mutable 区域和检索 - 可变
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...
- leetcode笔记:Range Sum Query - Mutable
一. 题目描写叙述 Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), ...
- Leetcode 2——Range Sum Query - Mutable(树状数组实现)
Problem: Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), ...
随机推荐
- struts2 具体学习资料
[struts2]<package>的配置:https://www.cnblogs.com/ningvsban/p/3734562.html struts2 具体学习资料 :http:/ ...
- memcache和iptables开启11211端口
linux下安装完memcached后,netstat -ant | grep LISTEN 看到memcache用的11211端口已在监听状态,但建立php文件连接测试发现没有输出结果,iptabl ...
- FloatHelper
function FloatHelper() { } FloatHelper.prototype.showFloater = function (Target, Title, Action, Acti ...
- fastjson格式化输出内容
引入fastjson <!--fastjson--><dependency> <groupId>com.alibaba</groupId> <ar ...
- ES6 Interator
Interator "集合"数据的结构主要有 Array .Object. Set and Map ,任何数据结构只要部署 Iterator 接口,就可完成遍历操作 遍历过程: 创 ...
- Android方法数methods超过65536
当Android App中的方法数超过65535时,如果往下兼容到低版本设备时,就会报编译错误: Cannot fit requested classes in a single dex file. ...
- Android Studio maven-metadata.xml 卡着不动原因和解决方法
头一天好好的,第二天就卡着了. 一直在这个地方不动,如果停止就会报 Error:Could not run build action using Gradle distribution ‘https: ...
- Git随笔:尝试将本地工程上传至Github上的repository仓库,构建远端与本地协同的Git环境
上传工程至自己的Github公开库,步骤如下: 第1步:建立本地 git 仓库,cd 到你的本地项目根目录下,执行 git init 命令: 第2步:将本地项目工作区的所有文件添加到暂存区.小数点 & ...
- Android中一个关于ListView的奇怪问题
今天在做项目的时候发现了一个比较奇怪的问题,是关于ListView的,即ListView的android:height属性会影响程序中ListView的getView()方法的调用次数,如果设置Lis ...
- A winner is a dreamer who never gives up
A winner is a dreamer who never gives up. 成功者是坚持梦想不放弃的人.(Nelson Mandela)