leetcode - Range Sum Query - Mutable

题目:

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


思路:

使用数据结构线段树,在NumArray的构造函数中递归构造线段树。


//线段树节点
class Node
{
public:
	int Min, Max, sum;//Min, Max表示该节点的区间为[Min,Max]
	Node* left, *right;
	Node(int a, int b, int c) :Min(a), Max(b), sum(c), left(NULL), right(NULL){}

};


class NumArray {
public:

	Node* root;
	vector<int> arr;
	NumArray(vector<int> &nums)
	{
		if (!nums.empty())
		{
			root = buildtree(nums, 0, nums.size() - 1).first;
			arr = vector<int>(nums);
		}

		else
			root = NULL;
	}

	pair<Node*, int> buildtree(vector<int> &nums, int l, int r)
	{
		if (l == r)
		{
			Node* res = new Node(l, r, nums[l]);
			return make_pair(res, nums[l]);
		}
		else
		{
			int mid = ((l + r) & 1) == 0 ? (l + r) >> 1 : ((l + r) >> 1) + 1;
			pair<Node*, int> ret1 = buildtree(nums, l, mid - 1), ret2 = buildtree(nums, mid, r);
			Node* res = new Node(l, r, ret1.second + ret2.second);
			res->left = ret1.first;
			res->right = ret2.first;
			return make_pair(res, ret1.second + ret2.second);
		}
	}

	void update(int i, int val) 
	{
		update_core(root, i, val);
		arr[i] = val;//重要!一定要改变arr对应的元素
	}

	void update_core(Node* root, int i, int val)
	{
		if (root == NULL)
			return;
		if (i >= root->Min && i <= root->Max)
		{
			root->sum -= arr[i];
			root->sum += val;
			update_core(root->left, i, val);
			update_core(root->right, i, val);
		}
	}



	int sumRange(int i, int j) {
		return seach(root, i, j);
	}

	int seach(Node* root, int i, int j)
	{
		if (root == NULL || i>j)
			return -1;
		if (root->Min == i && j == root->Max)
			return root->sum;
		int mid = ((root->Min + root->Max) & 1) == 0 ? (root->Min + root->Max) >> 1 : ((root->Min + root->Max) >> 1) + 1;
		if (mid <= i)
			return seach(root->right, i, j);
		else if (j <= mid - 1)
			return seach(root->left, i, j);
		else
		{
			return  seach(root->left, i, mid - 1) + seach(root->right, mid, j);
		}
	}

};


// Your NumArray object will be instantiated and called as such:
// NumArray numArray(nums);
// numArray.sumRange(0, 1);
// numArray.update(1, 10);
// numArray.sumRange(1, 2);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值