2020-04-25 22:57:32數組
線段樹是一棵二叉樹,他的每一個節點包含了兩個額外的屬性start
和end
用於表示該節點所表明的區間。start
和end
都是整數,並按照以下的方式賦值:ide
start
和 end
由 build
方法所給出。start=A.left, end=(A.left + A.right) / 2
。start=(A.left + A.right) / 2 + 1, end=A.right
。start
等於 end
, 那麼該節點是葉子節點,再也不有左右兒子。對於給定數組實現build
方法, 線段樹的每一個節點儲存區間最大值, 返回根節點。ui
/** * Definition of SegmentTreeNode: * public class SegmentTreeNode { * public int start, end, count; * public SegmentTreeNode left, right; * public SegmentTreeNode(int start, int end, int count) { * this.start = start; * this.end = end; * this.count = count; * this.left = this.right = null; * } * } */
public SegmentTreeNode build(int[] A) { return helper(A, 0, A.length - 1); } private SegmentTreeNode helper(int[] nums, int l, int r) { if (l > r) return null; if (l == r) return new SegmentTreeNode(l, r, nums[l]); int mid = l + (r - l) / 2; SegmentTreeNode left = helper(nums, l, mid); SegmentTreeNode right = helper(nums, mid + 1, r); SegmentTreeNode root = new SegmentTreeNode(l, r, Math.max(left.max, right.max)); root.left = left; root.right = right; return root; }
203. 線段樹的修改 this
對於一棵 最大線段樹, 每一個節點包含一個額外的 max
屬性,用於存儲該節點所表明區間的最大值。spa
設計一個 modify
的方法,接受三個參數 root
、 index
和 value
。該方法將 root 爲根的線段樹中 [start, end] = [index, index] 的節點修改成了新的 value ,並確保在修改後,線段樹的每一個節點的 max 屬性仍然具備正確的值。設計
public void modify(SegmentTreeNode root, int index, int value) { if (root.start == root.end) { root.max = value; return; } int mid = root.start + (root.end - root.start) / 2; if (index <= mid) modify(root.left, index, value); else modify(root.right, index, value); root.max = Math.max(root.left.max, root.right.max); }
202. 線段樹的查詢 code
對於一個有n個數的整數數組,在對應的線段樹中, 根節點所表明的區間爲0-n-1, 每一個節點有一個額外的屬性max
,值爲該節點所表明的數組區間start到end內的最大值。it
爲SegmentTree設計一個 query
的方法,接受3個參數root
, start
和end
,線段樹root所表明的數組中子區間[start, end]內的最大值。io
public int query(SegmentTreeNode root, int start, int end) { if (root.start == start && root.end == end) return root.max; int mid = root.start + (root.end - root.start) / 2; if (start > mid) return query(root.right, start, end); else if (end <= mid) return query(root.left, start, end); else return Math.max(query(root.left, start, mid), query(root.right, mid + 1, end)); }