Given an integer array nums, handle multiple queries of the following types:
Update the value of an element in nums.
Calculate the sum of the elements of nums between indices left and rightinclusive where left <= right.
Implement the NumArray class:
NumArray(int[] nums) Initializes the object with the integer array nums.
void update(int index, int val)Updates the value of nums[index] to be val.
int sumRange(int left, int right) Returns the sum of the elements of nums between indices left and rightinclusive (i.e. nums[left] + nums[left + 1] + ... + nums[right]).
At most 3 * 104 calls will be made to update and sumRange.
ac1: Binary Indexed Tree
careful: bit.length = nums.length + 1; so need to do i++ in methods
classNumArray {int[] bit;int[] nums;publicNumArray(int[] nums) {this.nums= nums; bit =newint[nums.length+1];for (int i =0; i <nums.length; i++) {int val = nums[i]; nums[i] =0;update(i, val); } }publicvoidupdate(int i,int val) {// index + last '1' bit int diff = val - nums[i]; nums[i] = val; i++;while (i <bit.length) { bit[i] += diff; i += i & (-i); } }privateintgetSum(int i) {// index - last '1' bit i++;int res =0;while (i >0) { res += bit[i]; i -= i & (-i); }return res; }publicintsumRange(int i,int j) {returngetSum(j)-getSum(i-1); }}/** * Your NumArray object will be instantiated and called as such: * NumArray obj = new NumArray(nums); * obj.update(i,val); * int param_2 = obj.sumRange(i,j); */
ac2: Segment Tree
more intuitive, yet more code. Notice: use divide and conquer, no need to care about the mid point unless building the tree.
classNumArray {classSegTreeNode{int start, end, sum;SegTreeNode left, right;publicSegTreeNode(int start,int end){this.start= start;this.end= end; sum =0; } }SegTreeNode root;publicNumArray(int[] nums) { root =build(nums,0,nums.length-1); }privateSegTreeNodebuild(int[] nums,int start,int end) {if (start <0|| end >=nums.length|| start > end) returnnull;int mid = start + (end - start) /2;SegTreeNode node =newSegTreeNode(start, end);if (start == end) {node.sum= nums[start]; } else {node.left=build(nums, start, mid);node.right=build(nums, mid+1, end);node.sum=node.left.sum+node.right.sum; }return node; }publicvoidupdate(int i,int val) {update(root, i, val); }privatevoidupdate(SegTreeNode root,int i,int val) {if (i <root.start|| i >root.end) return; // out of rangeif (root.start==root.end) {root.sum= val; // leaf, sum = nums[i]return; }// divide and conquerupdate(root.left, i, val);update(root.right, i, val);root.sum=root.left.sum+root.right.sum; }publicintsumRange(int i,int j) {returnsumRange(root, i, j); }privateintsumRange(SegTreeNode root,int i,int j) {if (i >root.end|| j <root.start) return0; // out of rangeif (i <=root.start&&root.end<= j) returnroot.sum; // current node within range, return value// divide and conquerint res =0; res +=sumRange(root.left, i, j); res +=sumRange(root.right, i, j);return res; }}/** * Your NumArray object will be instantiated and called as such: * NumArray obj = new NumArray(nums); * obj.update(i,val); * int param_2 = obj.sumRange(i,j); */