题目

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);
}
};

GitHub测试程序源码

LeetCode(307) Range Sum Query - Mutable的更多相关文章

  1. 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 ...

  2. 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 ...

  3. 【刷题-LeetCode】307. Range Sum Query - Mutable

    Range Sum Query - Mutable Given an integer array nums, find the sum of the elements between indices ...

  4. [Leetcode Week16]Range Sum Query - Mutable

    Range Sum Query - Mutable 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/range-sum-query-mutable/de ...

  5. 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 ...

  6. [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 ...

  7. [LeetCode] Range Sum Query - Mutable 区域和检索 - 可变

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

  8. leetcode笔记:Range Sum Query - Mutable

    一. 题目描写叙述 Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), ...

  9. 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), ...

随机推荐

  1. Tkinter 的三大布局管理器 pack、grid 和 place用法汇总

    学习python的tkinter免不了要对各个组件进行位置的排放与设定,常用的布局管理器有grid,pack和place.这三种均用于同一父组件下的组件布局,但是也是有区别的,先看下他们各自的含义吧. ...

  2. NET Core Web发布包

    给ASP.NET Core Web发布包做减法 https://www.cnblogs.com/sheng-jie/p/9122582.html 1.引言 紧接上篇:ASP.NET Core Web ...

  3. NET Core 模块化,多租户框架

    NET Core 模块化,多租户框架 Orchard Core Framework:ASP.NET Core 模块化,多租户框架 上一篇编写Orchard Core一分钟搭建ASP.NET Core ...

  4. Jenkins+Gitlab+Ansible自动化部署(一)

    首先准备实验环境 虚拟机 主机名 IP地址 服务 系统版本 内核版本 Vmware Workstation 14 gitlab.example.com 192.168.244.130 gitlab  ...

  5. spring cloud 测试的时候报 BeanCreationNotAllowedException: Error creating bean with name 'eurekaAutoServiceRegistration' 但能正确跑完测试方法

    因为都能正确的跑测试方法,所以我也不太注意它,但是有时候闲得蛋疼就会找一下原因. 具体原因我也说不清,直接丢个连接 https://github.com/spring-cloud/spring-clo ...

  6. MoinMoin install in apache (win)

    一:下载环境 xampp:http://sourceforge.net/projects/xampp/files/XAMPP%20Windows/1.8.1/xampp-win32-1.8.1-VC9 ...

  7. 常用快捷键—Webstorm

    常用快捷键—Webstorm入门指南 提高代码编写效率,离不开快捷键的使用,Webstorm拥有丰富的代码快速编辑功能,你可以自由配置功能快捷键. 快捷键配置 点击“File”-> “setti ...

  8. Class 类

    在javascript 中应用类的概念 // javascript web applications 富应用开发 // 类库:生成类的地方:给所有的构造函数提供基础方法,如 extend, inclu ...

  9. python3操作excel02(对excel的基础操作,进行简单的封装)3

    #!/usr/bin/env python# -*- coding:UTF-8 -*- import requestsfrom bs4 import BeautifulSoupfrom bs4 imp ...

  10. Linux下如何修改用户默认目录

      Linux下默认的用户目录一般为/home/xxx(root用户除外),有些时候我们可能需要修改这个目录,下面我就给大家分享2中修改的方法 工具/原料 Linux操作系统 方法/步骤 1 1.切换 ...