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

Given an integer array nums, find the sum of the elements between indices i and j (ij), 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:

1. The array is only modifiable by the update function.
2. You may assume the number of calls to update and sumRange function is distributed evenly.

class NumArray {
public:
NumArray(vector<int> nums) {
data = nums;
}

void update(int i, int val) {
data[i] = val;
}

int sumRange(int i, int j) {
int sum = 0;
for (int k = i; k <= j; ++k) {
sum += data[k];
}
return sum;
}

private:
vector<int> data;
};

class NumArray {
public:
NumArray(vector<int> nums) {
if (nums.empty()) return;
data = nums;
double root = sqrt(data.size());
len = ceil(data.size() / root);
block.resize(len);
for (int i = 0; i < data.size(); ++i) {
block[i / len] += data[i];
}
}

void update(int i, int val) {
int idx = i / len;
block[idx] += val - data[i];
data[i] = val;
}

int sumRange(int i, int j) {
int sum = 0;
int start = i / len, end = j / len;
if (start == end) {
for (int k = i; k <= j; ++k) {
sum += data[k];
}
return sum;
}
for (int k = i; k < (start + 1) * len; ++k) {
sum += data[k];
}
for (int k = start + 1; k < end; ++k) {
sum += block[k];
}
for (int k = end * len; k <= j; ++k) {
sum += data[k];
}
return sum;
}

private:
int len;
vector<int> data, block;
};

C1 = A1
C2 = A1 + A2
C3 = A3
C4 = A1 + A2 + A3 + A4
C5 = A5
C6 = A5 + A6
C7 = A7
C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8
...

1               0001          1

2               0010          2

3               0011          1

4               0100          4

5               0101          1

6               0110          2

7               011         1

8               1000          8

...

bit -> 0 1 4 5 18 11 24 15 74

0 1 4 5 18 11 24 15 74

0 1 4 2 18 11 24 15 74

0 1 4 2 15 11 24 15 74

0 1 4 2 15 11 24 15 71

class NumArray {
public:
NumArray(vector<int> nums) {
data.resize(nums.size());
bit.resize(nums.size() + 1);
for (int i = 0; i < nums.size(); ++i) {
update(i, nums[i]);
}
}

void update(int i, int val) {
int diff = val - data[i];
for (int j = i + 1; j < bit.size(); j += (j&-j)) {
bit[j] += diff;
}
data[i] = val;
}

int sumRange(int i, int j) {
return getSum(j + 1) - getSum(i);
}

int getSum(int i) {
int res = 0;
for (int j = i; j > 0; j -= (j&-j)) {
res += bit[j];
}
return res;
}

private:
vector<int> data, bit;
};

           [0, 3]
16
/            \
[0, 1]        [2, 3]
4             12
/     \       /     \
[0, 0] [1, 1] [2, 2] [3, 3]
1      3      5      7

_ _ _ _ 1 3 5 7

_ _ _ 12 1 3 5 7

_ _ 4 12 1 3 5 7

_ 16 4 12 1 3 5 7

0 16 4 12 1 3 2 7

0 16 4 9 1 3 2 7

0 13 4 9 1 3 2 7

13 13 4 9 1 3 2 7

class NumArray {
public:
NumArray(vector<int> nums) {
n = nums.size();
tree.resize(n * 2);
buildTree(nums);
}

void buildTree(vector<int>& nums) {
for (int i = n; i < n * 2; ++i) {
tree[i] = nums[i - n];
}
for (int i = n - 1; i > 0; --i) {
tree[i] = tree[i * 2] + tree[i * 2 + 1];
}
}

void update(int i, int val) {
tree[i += n] = val;
while (i > 0) {
tree[i / 2] = tree[i] + tree[i ^ 1];
i /= 2;
}
}

int sumRange(int i, int j) {
int sum = 0;
for (i += n, j += n; i <= j; i /= 2, j /= 2) {
if ((i & 1) == 1) sum += tree[i++];
if ((j & 1) == 0) sum += tree[j--];
}
return sum;
}

private:
int n;
vector<int> tree;
};

Github 同步地址：

https://github.com/grandyang/leetcode/issues/307

Range Sum Query 2D - Mutable

Range Sum Query 2D - Immutable

Range Sum Query - Immutable

https://leetcode.com/problems/range-sum-query-mutable/

https://leetcode.com/problems/range-sum-query-mutable/discuss/75763/7ms-Java-solution-using-bottom-up-segment-tree

https://leetcode.com/problems/range-sum-query-mutable/discuss/75785/Share-my-c%2B%2B-solution%3A-1700ms-using-tree-array

LeetCode All in One 题目讲解汇总(持续更新中...)

posted @ 2015-11-22 11:22  Grandyang  阅读(21127)  评论(12编辑  收藏  举报