Max Tree

根据给定无重复整数数组构建最大树,其中根节点为数组中最大值,左右子树分别是子数组的最大树。例:[4, 1, 3, 2] 构建的最大树中,根节点是4。挑战在于要求O(n)的时间和内存复杂度。暴力解法使用深度优先搜索会超时,最佳解决方案利用单调递减栈找到左右两侧第一个大于当前元素的点来构建节点。" 132219905,19673656,原子搜索算法在二进制特征选择中的应用,"['机器学习', '特征工程', '进化算法', '优化', 'Matlab编程']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given an integer array with no duplicates. A max tree building on this array is defined as follow:

  • The root is the maximum number in the array
  • The left subtree and right subtree are the max trees of the subarray divided by the root number.

Construct the max tree by the given array.

Example

Example 1:

Input:[2, 5, 6, 0, 3, 1]
Output:{6,5,3,2,#,0,1}
Explanation:
the max tree constructed by this array is:
    6
   / \
  5   3
 /   / \
2   0   1
Example 2:
Input:[6,4,20]
Output:{20,6,#,#,4}
Explanation: 
     20
     / 
    6
     \
      4

Challenge

O(n) time and memory.

思路:暴力解:用dfs;会time out;

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */

public class Solution {
    /**
     * @param A: Given an integer array with no duplicates.
     * @return: The root of max tree.
     */
    public TreeNode maxTree(int[] A) {
        if(A == null || A.length == 0 ) return null;
        return buildMaxTree(A, 0, A.length-1);
    }
    
    private TreeNode buildMaxTree(int[] A, int start, int end) {
        if(start > end) {
            return null;
        }
        if(start == end) {
            return new TreeNode(A[start]);
        }
        
        // find max;
        int index = start;
        for(int i = start; i<= end; i++) {
            if(A[i] >= A[index]){
                index = i;
            }
        }
        TreeNode root = new TreeNode(A[index]);
        root.left = buildMaxTree(A, start, index-1);
        root.right = buildMaxTree(A, index+1, end);
        return root;
    }
}

最优解:用单调递减栈,因为L, <x, <x....X, <x, <x, R, (L>X, R>X)  X能够给他父亲的,只能是L , R中的一个. 所以,这题变成了找左右两边第一个比X大的点,用单调递减栈;

取最小值,然后分别接到左右(看X是连接在L,R的左边还是右边);

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */

public class Solution {
    /**
     * @param A: Given an integer array with no duplicates.
     * @return: The root of max tree.
     */
    public TreeNode maxTree(int[] A) {
        if(A == null || A.length == 0) {
            return null;
        }
        
        Stack<TreeNode> stack = new Stack<TreeNode>();
        for(int i = 0; i <= A.length; i++) {
            TreeNode node = (i == A.length) ? new TreeNode(Integer.MAX_VALUE) 
                                            : new TreeNode(A[i]);
            while(!stack.isEmpty() && stack.peek().val <= node.val){
                TreeNode curnode = stack.pop();
                //核心就是安排pop出来的点,是去L,还是R的左边还是右边;
                // 注意因为上面pop了,这里一定要判断一下stack是否为空;
                if(!stack.isEmpty() && node.val > stack.peek().val) {
                    stack.peek().right = curnode;
                } else {
                    // node.val <= stack.peek().val;
                    node.left = curnode;
                }
            }
            stack.push(node);
        }
        return stack.pop().left;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值