線段樹-區間最值問題

2020-04-25 22:57:32數組

  • 439. 線段樹的構造 II

線段樹是一棵二叉樹,他的每一個節點包含了兩個額外的屬性startend用於表示該節點所表明的區間。startend都是整數,並按照以下的方式賦值:ide

  • 根節點的 start 和 end 由 build 方法所給出。
  • 對於節點 A 的左兒子,有 start=A.left, end=(A.left + A.right) / 2
  • 對於節點 A 的右兒子,有 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 爲根的線段樹中 [startend] = [indexindex] 的節點修改成了新的 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個參數rootstartend,線段樹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));
    }
相關文章
相關標籤/搜索