654. 最大二叉树


给定一个不含重复元素的整数数组 nums 。一个以此数组直接递归构建的 最大二叉树 定义如下:

二叉树的根是数组 nums 中的最大元素。
左子树是通过数组中 最大值左边部分 递归构造出的最大二叉树。
右子树是通过数组中 最大值右边部分 递归构造出的最大二叉树。
返回有给定数组 nums 构建的 最大二叉树 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

递归

class Solution {

    private int[] nums;

    private TreeNode solve(int l, int r) {
        if (l > r) {
            return null;
        }
        int index = maxIndex(l, r);
        TreeNode root = new TreeNode(nums[index]);
        root.left = solve(l, index - 1);
        root.right = solve(index + 1, r);
        return root;
    }

    private int maxIndex(int l, int r) {
        int ans = l;
        for (int i = l; i <= r; ++i) {
            if (nums[i] > nums[ans]) {
                ans = i;
            }
        }
        return ans;
    }

    public TreeNode constructMaximumBinaryTree(int[] nums) {
        this.nums = nums;
        return solve(0, nums.length - 1);
    }

}

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode() {
    }

    TreeNode(int val) {
        this.val = val;
    }

    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

线段树

import java.util.Arrays;

class Solution {

    private int[] nums;

    private SegmentTree segmentTree;

    private TreeNode solve(int l, int r) {
        if (l > r) {
            return null;
        }
        int index = segmentTree.query(l, r, 1, nums.length, 1);
        TreeNode root = new TreeNode(nums[index]);
        root.left = solve(l, index);
        root.right = solve(index + 2, r);
        return root;
    }

    public TreeNode constructMaximumBinaryTree(int[] nums) {
        this.segmentTree = new SegmentTree(nums);
        this.nums = nums;
        return solve(1, nums.length);
    }
}


class SegmentTree {
    private int[] original;
    private int[] max;

    public SegmentTree(int[] original) {
        this.original = original;
        this.max = new int[original.length << 2 | 1];
        Arrays.fill(this.max, Integer.MIN_VALUE);
        this.build();
    }

    private void pushUp(int rt) {
        if (original[max[rt << 1]] > original[max[rt << 1 | 1]]) {
            max[rt] = max[rt << 1];
        } else {
            max[rt] = max[rt << 1 | 1];
        }
    }

    private void build(int l, int r, int rt) {
        if (l == r) {
            max[rt] = l - 1;
            return;
        }
        int mid = (l + r) >> 1;
        if (l <= mid) {
            build(l, mid, rt << 1);
        }

        if (mid < r) {
            build(mid + 1, r, rt << 1 | 1);
        }
        pushUp(rt);
    }

    private int maxIndex(int index1, int index2) {
        if (index1 == -1) {
            return index2;
        }
        if (index2 == -1) {
            return index1;
        }
        return original[index1] > original[index2] ? index1 : index2;
    }

    public int query(int L, int R, int l, int r, int rt) {
        if (L <= l && R >= r) {
            return max[rt];
        }
        int index = -1;
        int mid = (l + r) >> 1;
        if (L <= mid) {
            int idx = query(L, R, l, mid, rt << 1);
            index = maxIndex(index, idx);
        }

        if (mid < R) {
            int idx = query(L, R, mid + 1, r, rt << 1 | 1);
            index = maxIndex(index, idx);
        }
        return index;
    }

    private void build() {
        build(1, original.length, 1);
    }
}

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode() {
    }

    TreeNode(int val) {
        this.val = val;
    }

    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

相关