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); Runtime : 11ms Memory : 45.4MB Logic : use segment tree for finding out the sum of the array at given range.
| 11 | |
| 12 | |
| 13 | class NumArray { |
| 14 | |
| 15 | int[] tree; |
| 16 | int n; |
| 17 | |
| 18 | public NumArray(int[] nums) { |
| 19 | if (nums.length > 0) { |
| 20 | n = nums.length; |
| 21 | tree = new int[n * 2]; |
| 22 | buildTree(nums); |
| 23 | } |
| 24 | } |
| 25 | |
| 26 | // build the segment tree and store it in array of size 2 * nums[] length |
| 27 | // so the nums[] values are stores at leaves of the segment tree. |
| 28 | private void buildTree(int[] nums) { |
| 29 | for (int i = n, j = 0; i < 2 * n; i++, j++) |
| 30 | tree[i] = nums[j]; |
| 31 | for (int i = n - 1; i > 0; --i) |
| 32 | tree[i] = tree[i * 2] + tree[i * 2 + 1]; |
| 33 | } |
| 34 | |
| 35 | // update the segment tree if new value to be inserted in tree, then update its parent at pos/2 and so on till root |
| 36 | void update(int pos, int val) { |
| 37 | pos += n; |
| 38 | tree[pos] = val; |
| 39 | while (pos > 0) { |
| 40 | int left = pos; |
| 41 | int right = pos; |
| 42 | if (pos % 2 == 0) { |
| 43 | right = pos + 1; |
| 44 | } else { |
| 45 | left = pos - 1; |
| 46 | } |
| 47 | // parent is updated after child is updated |
| 48 | tree[pos / 2] = tree[left] + tree[right]; |
| 49 | pos /= 2; |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | |
| 54 | // this is responsible for the sum betweeen given ranges |
| 55 | public int sumRange(int l, int r) { |
| 56 | // get leaf with value 'l' |
| 57 | l += n; |
| 58 | // get leaf with value 'r' |
| 59 | r += n; |
| 60 | int sum = 0; |
| 61 | while (l <= r) { |
| 62 | if ((l % 2) == 1) { |
| 63 | sum += tree[l]; |
| 64 | l++; |
| 65 | } |
| 66 | if ((r % 2) == 0) { |
| 67 | sum += tree[r]; |
| 68 | r--; |
| 69 | } |
| 70 | l /= 2; |
nothing calls this directly
no outgoing calls
no test coverage detected