Advertisement
1988coder

307. Range Sum Query - Mutable

Dec 26th, 2018
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.33 KB | None | 0 0
  1. /*
  2. Using Segment Tree
  3.  
  4. Time Complexity:
  5. 1. NumArray = O(N)
  6. 2. update = O(log N)
  7. 3. sumRange = O(log N)
  8.  
  9. Space Complexity: O(N)
  10. */
  11. class NumArray {
  12.    
  13.     private class SegmentTreeNode {
  14.         int start;
  15.         int end;
  16.         int sum;
  17.         SegmentTreeNode left;
  18.         SegmentTreeNode right;
  19.        
  20.         SegmentTreeNode (int s, int e) {
  21.             start = s;
  22.             end = e;
  23.         }
  24.     }
  25.    
  26.     SegmentTreeNode root;
  27.    
  28.     public NumArray(int[] nums) {
  29.         root = buildTree(nums, 0, nums.length-1);
  30.     }
  31.    
  32.     private SegmentTreeNode buildTree(int[] nums, int s, int e) {
  33.         if (s > e) {
  34.             return null;
  35.         }
  36.         SegmentTreeNode node = new SegmentTreeNode(s, e);
  37.         if (s == e) {
  38.             node.sum = nums[s];
  39.         } else {
  40.             int mid = s + (e-s)/2;
  41.             node.left = buildTree(nums, s, mid);
  42.             node.right = buildTree(nums, mid+1, e);
  43.             node.sum = node.left.sum + node.right.sum;
  44.         }
  45.         return node;
  46.     }
  47.    
  48.     public void update(int i, int val) {
  49.         updateTree(root, i, val);
  50.     }
  51.    
  52.     private void updateTree(SegmentTreeNode node, int i, int val) {
  53.         if (node.start == node.end && node.start == i) {
  54.             node.sum = val;
  55.             return;
  56.         }
  57.         int mid = node.start + (node.end - node.start)/2;
  58.         if (i <= mid) {
  59.             updateTree(node.left, i, val);
  60.         } else {
  61.             updateTree(node.right, i, val);
  62.         }
  63.         node.sum = node.left.sum + node.right.sum;
  64.     }
  65.    
  66.     public int sumRange(int i, int j) {
  67.         return sumRange(root, i, j);
  68.     }
  69.    
  70.     private int sumRange(SegmentTreeNode node, int i , int j) {
  71.         if (node.start == i && node.end == j) {
  72.             return node.sum;
  73.         }
  74.         int mid = node.start + (node.end - node.start)/2;
  75.         if (j <= mid) {
  76.             return sumRange(node.left, i, j);
  77.         }
  78.         if (i > mid) {
  79.             return sumRange(node.right, i, j);
  80.         }
  81.         return sumRange(node.left, i, mid) + sumRange(node.right, mid+1, j);
  82.     }
  83. }
  84.  
  85.  
  86. /*
  87. Using Binary Indexed Tree
  88. Refer:
  89. 1) https://leetcode.com/problems/range-sum-query-mutable/discuss/75753/Java-using-Binary-Indexed-Tree-with-clear-explanation
  90. 2) https://www.topcoder.com/community/competitive-programming/tutorials/binary-indexed-trees/
  91.  
  92. Time Complexity:
  93. 1. NumArray = O(N logN)
  94. 2. update = O(log N)
  95. 3. sumRange = O(log N)
  96.  
  97. Space Complexity: O(N)
  98. */
  99. class NumArray {
  100.     int[] numArr;
  101.     int[] tree;
  102.     int maxIdx;
  103.    
  104.     public NumArray(int[] nums) throws IllegalArgumentException {
  105.         if (nums == null) {
  106.             throw new IllegalArgumentException("Input nums array is null");
  107.         }
  108.         numArr = nums;
  109.         int len = numArr.length;
  110.         tree = new int[len+1];
  111.         maxIdx = len;
  112.        
  113.         for (int i = 0; i < len; i++) {
  114.             updateHelper(i+1, numArr[i]);
  115.         }
  116.     }
  117.    
  118.     public void update(int i, int val) {
  119.         int diff = val - numArr[i];
  120.         numArr[i] = val;
  121.         updateHelper(i+1, diff);
  122.     }
  123.    
  124.     private void updateHelper(int i, int diff) {
  125.         while (i <= maxIdx) {
  126.             tree[i] += diff;
  127.             i += i & -i;
  128.         }
  129.     }
  130.    
  131.     public int sumRange(int i, int j) {
  132.         return readIdx(j+1) - readIdx(i);
  133.     }
  134.    
  135.     private int readIdx(int idx) {
  136.         int sum = 0;
  137.         while (idx > 0) {
  138.             sum += tree[idx];
  139.             idx &= idx-1;
  140.         }
  141.         return sum;
  142.     }
  143. }
  144.  
  145.  
  146. /*
  147. Using Binary Indexed Tree with optimization.
  148. It uses cumulative sum array for initializing the tree;
  149. Refer:
  150. 1) https://leetcode.com/problems/range-sum-query-mutable/discuss/75753/Java-using-Binary-Indexed-Tree-with-clear-explanation/166940
  151. 2) https://www.topcoder.com/community/competitive-programming/tutorials/binary-indexed-trees/
  152.  
  153. Time Complexity:
  154. 1. NumArray = O(N)
  155. 2. update = O(log N)
  156. 3. sumRange = O(log N)
  157.  
  158. Space Complexity: O(N)
  159. */
  160. class NumArray {
  161.     int[] numArr;
  162.     int[] tree;
  163.     int maxIdx;
  164.    
  165.     public NumArray(int[] nums) throws IllegalArgumentException {
  166.         if (nums == null) {
  167.             throw new IllegalArgumentException("Input nums array is null");
  168.         }
  169.        
  170.         numArr = nums;
  171.         maxIdx = nums.length;
  172.        
  173.         int[] csArr = new int[maxIdx+1];
  174.         for (int i = 0; i < maxIdx; i++) {
  175.             csArr[i+1] = csArr[i] + nums[i];
  176.         }
  177.        
  178.         tree = new int[maxIdx+1];
  179.        
  180.         for (int i = 1; i <= maxIdx; i++) {
  181.             tree[i] = csArr[i] - csArr[i - (i & -i)];
  182.         }
  183.     }
  184.    
  185.     public void update(int i, int val) {
  186.         int diff = val - numArr[i];
  187.         numArr[i] = val;
  188.         i++;
  189.         while (i <= maxIdx) {
  190.             tree[i] += diff;
  191.             i += i & -i;
  192.         }
  193.     }
  194.    
  195.     public int sumRange(int i, int j) {
  196.         return readIdx(j+1) - readIdx(i);
  197.     }
  198.    
  199.     private int readIdx(int idx) {
  200.         int sum = 0;
  201.         while (idx > 0) {
  202.             sum += tree[idx];
  203.             idx &= idx-1;
  204.         }
  205.         return sum;
  206.     }
  207. }
  208.  
  209. /**
  210.  * Your NumArray object will be instantiated and called as such:
  211.  * NumArray obj = new NumArray(nums);
  212.  * obj.update(i,val);
  213.  * int param_2 = obj.sumRange(i,j);
  214.  */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement