307. 區域和檢索-陣列不可變
阿新 • • 發佈:2021-11-10
class NumArray { SegmentTree segmentTree; public NumArray(int[] nums) { segmentTree = new SegmentTree(nums); } public void update(int index, int val) { segmentTree.update(index, val); } public int sumRange(int left, int right) { return segmentTree.sumRange(left, right); } } /** * 使用線段樹對區間求和,更新區間值 */ class SegmentTree { int[] data; int[] tree; public SegmentTree(int[] arr){ data = arr; tree = new int[data.length * 4]; buildSegmentTree(0, 0, data.length - 1); } public void buildSegmentTree(int treeIndex, int left, int right){ if (left == right){ tree[treeIndex] = data[left]; return; } int mid = left + (right - left) / 2; buildSegmentTree(leftChild(treeIndex), left, mid); buildSegmentTree(rightChild(treeIndex), mid + 1, right); tree[treeIndex] = tree[leftChild(treeIndex)] + tree[rightChild(treeIndex)]; } public void update(int index, int val){ data[index] = val; update(0, 0, data.length - 1, index, val); } private void update(int treeIndex, int left, int right, int index, int val){ if (left == right){ tree[treeIndex] = val; return; } int mid = left + (right - left)/ 2; if (index >= mid + 1){ update(rightChild(treeIndex), mid + 1, right, index, val); } else { update(leftChild(treeIndex), left, mid, index, val); } tree[treeIndex] = tree[leftChild(treeIndex)] + tree[rightChild(treeIndex)]; } public int sumRange(int left, int right){ return sumRange(0, 0, data.length - 1, left, right); } private int sumRange(int treeIndex, int l, int r, int left, int right){ if (l == left && r == right){ return tree[treeIndex]; } int mid = l + (r - l) / 2; if (left >= mid + 1){ return sumRange(rightChild(treeIndex), mid + 1, r, left, right); } else if (right <= mid){ return sumRange(leftChild(treeIndex), l, mid, left, right); } else { int resLeft = sumRange(leftChild(treeIndex), l, mid, left, mid); int resRight = sumRange(rightChild(treeIndex), mid + 1, r, mid + 1, right); return resLeft + resRight; } } public int leftChild(int index){ return 2 * index + 1; } public int rightChild(int index){ return 2 * index + 2; } }