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

思路:

segment tree基础,创建tree用分治,求sum要注意所求的区间和节点区间的关系。

算法:

public class NumArray {

	Node root = null;

	public NumArray(int[] nums) {
		root = create(nums, 0, nums.length - 1);
	}

	void update(int i, int val) {
		update(root, i, val);
	}

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

	public class Node {
		int lidx;
		int ridx;
		int val;
		Node lchild;
		Node rchild;

		public Node(int lidx, int ridx, int val) {
			this.lidx = lidx;
			this.ridx = ridx;
			this.val = val;
		}

	}

	public Node create(int[] nums, int l, int r) {
		if (l == r)
			return new Node(l, r, nums[r]);
		Node lchild = create(nums, l, (l + r) / 2);
		Node rchild = create(nums, (l + r) / 2 + 1, r);
		Node root = new Node(lchild.lidx, rchild.ridx, lchild.val + rchild.val);
		root.lchild = lchild;
		root.rchild = rchild;
		return root;
	}

	public int sum(Node root, int l, int r) {
		if (root.ridx < l || root.lidx > r)// 所求区间与节点区间不相交
			return 0;

		if (l <= root.lidx && root.ridx <= r)// 所求区间包含了 节点区间
			return root.val;

		return sum(root.lchild, l, r) + sum(root.rchild, l, r);//所求区间和节点区间相交
	}

	int diff = 0;// 需要从index叶节点 往上更新的值
	public void update(Node root, int index, int newVal) {
		if (root.lidx == root.ridx && index == root.lidx) {// 要更新的叶节点
			diff = newVal - root.val;
			root.val = newVal;
			return;
		}
		if (index <= (root.lidx + root.ridx) / 2)
			update(root.lchild, index, newVal);
		else
			update(root.rchild, index, newVal);

		root.val += diff;
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值