ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

leetcode 最大二叉树

2021-11-06 22:05:35  阅读:131  来源: 互联网

标签:TreeNode 最大 nums int 元素 栈顶 节点 二叉树 leetcode


题目链接
思路一:递归
分析:题目就是让找出每次在范围内的最大值为根节点

代码:

/**
 * Definition for a binary tree node.
 * public 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;
 *     }
 * }
 */
class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
    	//最大值所在的下标
        int maxIndex = 0;
        //最大值
        int max = -1;
        for(int i = 0 ; i < nums.length;i++){
            if(max < nums[i]){
                max = nums[i];
                maxIndex = i;
            }
        }
        //这就是最后的根节点
        TreeNode res = new TreeNode(max);
        //递归  找出左子树的根节点
        res.left =  divide(nums,0,maxIndex-1);
        //递归找出右子树的根节点
        res.right = divide(nums,maxIndex+1,nums.length-1);
        return res;
    }

	//递归找出在[left,right]范围内的最大值作为根节点
    public TreeNode divide(int[] nums,int left,int right){
		//找到出口条件
        if(left>right){
            return null;
        }
        
        //和上面的代码同理,找到最大的
        int maxIndex = -1;
        int max = -1;
        for(int i = left;i<=right;i++){
            if(max<nums[i]){
                max = nums[i];
                maxIndex = i;
            }
        }
        //这是在这个范围内的根节点
        TreeNode root = new TreeNode(max);
        //同理
        root.left = divide(nums, left,maxIndex-1);
        root.right = divide(nums,maxIndex+1,right);
        //返回此时的根节点
        return root;
    }
}

最坏时间复杂度:O(n2)

思路二:单调栈

要找最大的作为根节点,那么我们需要一个栈底到栈顶依次减小的单调栈,当遇到栈顶小于当前元素时:
分析:此时的栈顶肯定在当前元素的左子树里面,但不一定就是当前元素左子树的根节点,因为不一定是当前元素左边元素中最大的,所以先取出当前元素,看看栈内下一个元素。
情况一:下一个元素要是比当前元素小:此时(top0<cur && top1 < cur && top0 < top1),此时应该是top0是top1的右子树节点,然后又回到了前面的情况,此时栈顶元素依然小于当前元素。
情况二:下一个元素要是比当前元素大,那么就说明,刚刚取出来的栈顶元素肯定就是当前元素的左子树的根节点,因为栈内下一个元素就比当前元素大了,那么当前元素的左子树根节点指向刚刚的栈顶元素,然后将当前元素放入栈顶。

最后,局部最大的元素都在栈内了,最大的在栈底。
从栈顶开始遍历,栈顶的依次是下面元素的右子树根节点。
代码:

public TreeNode constructMaximumBinaryTree(int[] nums) {
        int len = nums.length;
        int top = -1;
        TreeNode[] stack = new TreeNode[len];
        //当前节点
        TreeNode curNode = null;

        for(int i = 0 ; i < len;i++){
            curNode = new TreeNode(nums[i]);

            //如果当前栈不为空,并且当前栈顶元素小于当前节点
            while (top!=-1 && stack[top].val < curNode.val){
                //取出当前栈顶元素
                TreeNode topNode = stack[top--];

                //栈不空,并且当前栈顶元素依然小于当前元素  说明刚刚那个栈顶只是当前栈顶的一个右节点,而不是当前元素的左节点
                if(top!=-1 && stack[top].val < curNode.val){
                    //当前栈顶元素的元素就是之前的栈顶元素
                    stack[top].right = topNode;
                }else{
                    //否则,当前元素的左节点就是之前的栈顶
                    curNode.left = topNode;
                }
            }

            //当前元素入栈
            stack[++top] = curNode;
        }
        //此时最大的元素在栈底,   从栈顶开始遍历
        while (top!=-1){
            //取出栈顶元素
            curNode = stack[top--];
            if(top!=-1){
                //此时的栈顶的右节点就是之前的栈顶元素
                stack[top].right = curNode;
            }
        }
        return curNode;
    }

以防小伙伴还是看不懂,下面图解:
nums={3,2,1,6,0,5}
在这里插入图片描述

栈空,直接进

在这里插入图片描述
栈顶大于当前元素,也入栈

在这里插入图片描述
栈顶大于当前元素,也入栈

在这里插入图片描述
此时当前元素大于栈顶元素
栈顶元素出栈

在这里插入图片描述
此时栈顶元素依然小于之前的栈顶元素(topNode)
此时的栈顶元素的右子树根节点就是刚刚的栈顶元素

在这里插入图片描述
此时栈顶元素还是小于当前元素,出栈

在这里插入图片描述
此时栈顶依然小于当前元素,刚刚的栈顶是此时栈顶的右子树根节点

在这里插入图片描述
同理,出栈

在这里插入图片描述
此时栈空,此时刚刚的栈顶元素就是当前元素的左子树的根节点:
在这里插入图片描述
栈空,入栈

在这里插入图片描述
此时栈顶大于当前元素,入栈

在这里插入图片描述

此时当前元素5大于栈顶0
在这里插入图片描述
0出栈,5小于6,然后0就是5的左子树根节点
在这里插入图片描述

当前元素5小于栈顶元素6,入栈

在这里插入图片描述
此时栈内只有两个元素,5,6,从栈顶开始遍历,上面的一定是下面的右子树。

在这里插入图片描述
结束。

标签:TreeNode,最大,nums,int,元素,栈顶,节点,二叉树,leetcode
来源: https://blog.csdn.net/weixin_42496727/article/details/121185183

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有