线段树详解(https://www.bilibili.com/video/av47331849)
上面这个视频详细介绍了线段树的创建、更新、与查询操作,看懂这个视频,基本上就会写线段树了。
307. Range Sum Query - Mutable
提交之后AC代码如下:
class NumArray {
private int[] nums = null;
private int[] nodes = null;
private int numLen = 0;
private int nodeLen = 0;
public NumArray(int[] nums) {
if (nums.length == 0) return;
this.nums = nums;
numLen = nums.length;
nodeLen = 4 * nums.length + 4;
this.nodes = new int[nodeLen];
buildTree(0, numLen - 1, 1);
}
public void update(int i, int val) {
nums[i] = val;
updateTree(0, numLen - 1, i, 1);
}
public int sumRange(int i, int j) {
return querySumTree(0, numLen - 1, i, j, 1);
}
private int querySumTree(int start, int end, int leftQ, int rightQ, int rootNode) {
if (leftQ > end || rightQ < start) {
return 0;
}
if (start == end) {
return nums[start];
}
if (leftQ <= start && rightQ >= end) {
return nodes[rootNode];
}
int mid = (start + end) / 2;
int leftSum = querySumTree(start, mid, leftQ, rightQ, rootNode * 2);
int rightSum = querySumTree(mid + 1, end, leftQ, rightQ, rootNode * 2 + 1);
return leftSum + rightSum;
}
private void updateTree(int start, int end, int updateIndex, int rootNode) {
if (start == end) {
nodes[rootNode] = nums[start];
return;
}
int mid = (start + end) / 2;
if (updateIndex >= start && updateIndex <= mid) {
updateTree(start, mid, updateIndex,rootNode * 2);
} else {
updateTree(mid + 1, end, updateIndex, rootNode * 2 + 1);
}
nodes[rootNode] = nodes[rootNode * 2] + nodes[rootNode * 2 + 1];
}
private void buildTree(int start, int end, int rootNode) {
if (start == end) {
nodes[rootNode] = nums[start];
return;
}
int mid = (start + end) / 2;
buildTree(start, mid, rootNode * 2);
buildTree(mid + 1, end, rootNode * 2 + 1);
nodes[rootNode] = nodes[rootNode * 2] + nodes[rootNode * 2 + 1];
}
}