Range Sum Query - Mutable
题目地址:
https://leetcode.com/problems/range-sum-query-mutable/description/
题目:
解题思路:
这道题可以用辅助的array来做,记录从当前节点到之前所有元素的和。但是会TLE。
代码:
we could use SegmentTree(线段树) to do this: time: O(log(n)), space: O(n):
I got the idea from this page:
http://blog.csdn.net/xing1989/article/details/9464677
My code revised from this page:
http://algs4.cs.princeton.edu/99misc/SegmentTree.java.html
这道题还有一个Follow up,就是当输入是2D数组的时候。这个时候如果是segmentTree的话,heap是一个四叉树。或者也可以建一个一维度的segment tree。

https://leetcode.com/problems/range-sum-query-mutable/description/
题目:
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
解题思路:
这道题可以用辅助的array来做,记录从当前节点到之前所有元素的和。但是会TLE。
代码:
private int[] sums; private int[] input; public NumArray(int[] nums) { sums = new int[nums.length]; input = new int[nums.length]; int prev = 0; for(int i = 0; i <= nums.length - 1; i++){ input[i] = nums[i]; sums[i] = prev + nums[i]; prev = sums[i]; } } public void update(int i, int val) { int diff = val - input[i]; input[i] = val; while(i <= input.length - 1){ sums[i] += diff; i++; } } public int sumRange(int i, int j) { if(i == 0){ return sums[j]; } else{ return sums[j] - sums[i - 1]; } }
I got the idea from this page:
http://blog.csdn.net/xing1989/article/details/9464677
My code revised from this page:
http://algs4.cs.princeton.edu/99misc/SegmentTree.java.html
// good stuff: also use O(n) space , but time complexity is O(lgn) private Node[] heap; private int[] array; private int size; // build a map to store the index if the array and the index in the heap. private Map<Integer, Integer> map; class Node{ int from; int to; int sum; } public NumArray(int[] nums) { this.array = Arrays.copyOf(nums, nums.length); map = new HashMap<>(); //The max size of this array is about 2 * 2 ^ log2(n) - 1 size = (int) (2 * Math.pow(2.0, Math.floor((Math.log((double) nums.length) / Math.log(2.0)) + 1))); heap = new Node[size]; build(0, 0, array.length); } private void build(int index, int from, int size) { if(size == 0){ return; } heap[index] = new Node(); heap[index].from = from; heap[index].to = from + size - 1; if(size == 1){ heap[index].sum = array[from]; map.put(from, index); } else{ // build the left heap build(index * 2 + 1, from, size - size / 2); // build the right heap build(index * 2 + 2, from + size - size / 2, size / 2); // left child index: 2 * index + 1 , right child index: 2 * index + 2 heap[index].sum = heap[index * 2 + 1].sum + heap[index * 2 + 2].sum; } } public void update(int i, int val) { int currIndex = map.get(i); heap[currIndex].sum = val; int parentIndex = (currIndex - 1) / 2; while(currIndex != 0){ int theOtherChildIndex = parentIndex * 2 + 1 == currIndex ? parentIndex * 2 + 2 : parentIndex * 2 + 1; heap[parentIndex].sum = heap[currIndex].sum + heap[theOtherChildIndex].sum; currIndex = parentIndex; parentIndex = (currIndex - 1) / 2; } } public int sumRange(int i, int j) { int rst = query(0, i, j); return rst; } private int query(int curr, int from, int to) { Node node = heap[curr]; if(node == null){ return 0; } if(isRange(from, to ,node)){ return node.sum; } else if (contains(from, to, node)) { Node left = heap[curr * 2 + 1]; Node right = heap[curr * 2 + 2]; int rst = 0; if(left != null){ rst += left.to >= from ? query(curr * 2 + 1, from, Math.min(left.to, to)) : 0; } if(right != null){ rst += to >= right.from ? query(curr * 2 + 2, Math.max(right.from, from), to) : 0; } return rst; } else{ return 0; } } private boolean isRange(int from, int to, Node node) { return node.from == from && node.to == to; } private boolean contains(int from, int to, Node node) { return node.from <= from && node.to >= to; } public static void main(String[] args){ // int[] nums = {1, 3, 5, 7, 9, 11}; int[] nums = {0, 9, 5, 7, 3}; NumArray numArray = new NumArray(nums); // numArray.printHeap(numArray.heap); int rst = numArray.sumRange(4, 4); System.out.println(rst); // numArray.update(3, 8);// rst = numArray.sumRange(0, 5);// System.out.println(rst); } private void printHeap(Node[] nums){ for(int i = 0; i <= nums.length - 1; i++){ if(nums[i] != null){ System.out.print(nums[i].sum); if(i != nums.length - 1){ System.out.print("->"); } } } }
这道题还有一个Follow up,就是当输入是2D数组的时候。这个时候如果是segmentTree的话,heap是一个四叉树。或者也可以建一个一维度的segment tree。


Comments
Post a Comment