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.

给定一个整型数组,找出数组下标i到j的元素的和。

给定一个更新操作,update(i,val)将第i个元素更新为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.
  1. 数组只能被update方法更改。
  2. 假设update和sumRange被均匀调用。

首先尝试用数组sums的第i个元素存储[0:i]的和,这样的话:sumRange的时间复杂度为O(1),由于每次update(i,val)都要更新下标i之后的sums,所以时间复杂度为O(n),由于update和sumRange被均匀调用,所以整个操作的时间复杂度为O(n);另外需要n个元素的存储空间。

这样的话,不出意外的TLE了。

考虑用二叉树存储部分和。

构造一个完全二叉树,最后一层存储原始数组元素,其余每一层存储下一层对应左右孩子节点之和,使用二维数组tree[][]存储这颗完全二叉树,tree[0]存储原始数组,tree[i][j]存储tree[i-1][j*2]和tree[i-1][j*2+1]之和,其中i>0,j>=0;

sumRange(i,j)的求法:

由于i<=j,所以只需要同时从tree[0][i]和tree[0][j]向上遍历到最近的共同祖先节点pf即可,搜索过程中以s1记录以pf为根的这棵树中i之前所有元素之和,以s2记录j之前所有元素之和,最后结果就是:s2-s1+tree[0][i];

s1的更新方法:

若当前遍历的节点i‘为父节点i‘‘的右孩子,则另s1加上i‘‘左孩子的值;若为左孩子则不需要更新;

s2的更新方法:

若当前遍历的节点j‘为父节点j‘‘的右孩子,则另s2加上j‘‘左孩子的值;若为左孩子则不需要更新;

update(i,val)的操作:

依次按tree[0][i],tree[1][i/2],...的顺序一直更新到根节点即可;

复杂度:

sumRange和update最多遍历次数均为logn次,空间复杂度为O(n);

class NumArray
{
private:
	vector<vector<int>> tree;
	int rows, cols;
public:
	NumArray(vector<int> &nums)
	{
		int r = 0, c = nums.size();
		if ((cols = c) == 0)
		{
			rows = 0;
			return;
		}

		tree.push_back(nums);
		while (1)
		{
			int size = tree[r].size();
			if (size == 1)		break;

			vector<int> sums;
			for (int i = 0;i < size;i += 2)
			{
				if (i + 1 < size)
				    sums.push_back(tree[r][i] + tree[r][i + 1]);
				else
				    sums.push_back(tree[r][i]);
			}
			tree.push_back(sums);
			++r;
		}
		rows = r + 1;
	}

	void update(int i, int val)
	{
		int delta = val - tree[0][i];

		for (int j = 0;j < rows;++j)
		{
			tree[j][i] += delta;
			i = i / 2;
		}
	}

	int sumRange(int i, int j)
	{
		if (i < 0 || i >= cols || j < 0 || j >= cols)	return 0;

		int r, s1, s2, i0, i_, j_;
		r = 0;
		s1 = tree[r][i];
		s2 = tree[r][j];
		i0 = i;

		while (i != j)
		{
			i_ = i / 2;
			j_ = j / 2;

			if (i_ * 2 + 1 == i)	// i is the right child of his parent
			{
				s1 += tree[r][i - 1];
			}
			if (j_ * 2 + 1 == j)	// j is the right child of his parent
			{
				s2 += tree[r][j - 1];
			}
			++r;
			i = i_;
			j = j_;
		}
		return s2 - s1 + tree[0][i0];
	}
};
时间: 2024-08-09 00:42:55

Leetcode 307. Range Sum Query - Mutable的相关文章

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

307. Range Sum Query - Mutable

/* * 307. Range Sum Query - Mutable * 2016-7-3 by Mingyang * 丧心病狂的Segment Tree,无语了 */ class NumArray { class SegmentTreeNode { int start, end; SegmentTreeNode left, right; int sum; public SegmentTreeNode(int start, int end) { this.start = start; this

[email&#160;protected] [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

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), 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 up

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 updat

LeetCode Range Sum Query - Mutable

原题链接在这里:https://leetcode.com/problems/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 v

LeetCode:Range Sum Query - Immutable - 数组指定区间内的元素和

1.题目名称 Range Sum Query(数组指定区间内的元素和) 2.题目地址 https://leetcode.com/problems/range-sum-query-immutable/ 3.题目内容 英文:Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive. 中文:给定一个数组nums,求出索引i和j之间元素的和,i一定是小于或等于j

leetCode 303. Range Sum Query - Immutable | Dynamic Programming

303. Range Sum Query - Immutable Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive. Example: Given nums = [-2, 0, 3, -5, 2, -1] sumRange(0, 2) -> 1 sumRange(2, 5) -> -1 sumRange(0, 5) -> -3 Note:

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