代码随想录-Day20

1.LeetCode 654.最大1二叉树

题目链接:力扣链接

参考资料代码随想录

视频讲解:

给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:

  1. 创建一个根节点,其值为 nums 中的最大值。
  2. 递归地在最大值 左边 的 子数组前缀上 构建左子树。
  3. 递归地在最大值 右边 的 子数组后缀上 构建右子树。

返回 nums 构建的 最大二叉树 

示例 1:

输入:nums = [3,2,1,6,0,5]
输出:[6,3,5,null,2,0,null,null,1]
解释:递归调用如下所示:
- [3,2,1,6,0,5] 中的最大值是 6 ,左边部分是 [3,2,1] ,右边部分是 [0,5] 。
    - [3,2,1] 中的最大值是 3 ,左边部分是 [] ,右边部分是 [2,1] 。
        - 空数组,无子节点。
        - [2,1] 中的最大值是 2 ,左边部分是 [] ,右边部分是 [1] 。
            - 空数组,无子节点。
            - 只有一个元素,所以子节点是一个值为 1 的节点。
    - [0,5] 中的最大值是 5 ,左边部分是 [0] ,右边部分是 [] 。
        - 只有一个元素,所以子节点是一个值为 0 的节点。
        - 空数组,无子节点。

思路:构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。

1.递归的返回值和传参:返回的是TreeNode,传参的话是数组类型的,我们新建一个方法来进行递归,那就要定好root节点2边的遍历位置,那就要传一个leftindex和一个rightindex的值,那就是传nums,int leftindex,int rightindexx;

2.确定递归的终止条件:当nums== 0的时候就返回null;当只有一个值的时候,也进行返回。

3.单边的递归条件:采用前序遍历,那优先处理中节点,找到一个最大值作为根节点,nums左边的是在左孩子,最大值的右边是有孩子,那么左孩子的递归条件就是,num,leftindex,maxindex(左闭右开),右节点的递归条件就是num,maxindex+1,rightindex;最后返回root节点

java代码具体如下:

class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return rever(nums,0,nums.length);
    }
    public TreeNode rever(int[] nums,int leftIndex,int rightIndex){
        if (rightIndex - leftIndex < 1) {// 没有元素了
            return null;
        }
        if (rightIndex - leftIndex == 1) {// 只有一个元素
            return new TreeNode(nums[leftIndex]);
        }
        int maxIndex = leftIndex;
        int maxVal = nums[maxIndex];
        for(int i = leftIndex+1;i < rightIndex;i++){
            if(nums[i] > maxVal){
                maxVal = nums[i];
                maxIndex = i;
            }
        }
        TreeNode root = new TreeNode(maxVal);
        root.left = rever(nums,leftIndex,maxIndex);
        root.right = rever(nums,maxIndex+1,rightIndex);
        return root;
    }
}

2.LeetCode 617.合并二叉树

题目链接:力扣链接

参考资料代码随想录

视频讲解:B站视频讲解

给你两棵二叉树: root1 和 root2 。

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

注意: 合并过程必须从两个树的根节点开始。

示例 1:

输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]

 递归思路:

1.确定传参和返回值:传参是2个treenode,root1和root2,返回值是treenode;

2.确定终止条件:root1为空就返回root2,root2为空就返回root1;

3.单边递归条件:同时传2个节点的值;

java代码如下:

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1 == null) return root2;
        if(root2 == null) return root1;
        root1.val += root2.val;
        root1.left = mergeTrees(root1.left,root2.left);
        root1.right = mergeTrees(root1.right,root2.right);
        return root1;

    }
}

 思路二:迭代法:

1.如果2个treenode有一个为空,则返回另外一个treenode;

2.创建栈,把root1和root2同时压入栈;

3.当栈不为空,开始层序遍历,走前序遍历,结合栈的特点(先进后出),我们优先压入右侧入栈,在压入左侧;

4.当2个左右都不为空,我们就将2个数据都入栈,如果其中一个为空,那我们就补充这个数字;

最后返回栈root;

java代码如下:

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1 == null) return root2;
        if(root2 == null) return root1;
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root2);
        stack.push(root1);
        while (!stack.isEmpty()){
            TreeNode temp1 = stack.pop();
            TreeNode temp2 = stack.pop();
            temp1.val += temp2.val;
            if(temp1.right != null && temp2.right != null){
                stack.push(temp2.right);
                stack.push(temp1.right);
            }else{
                if(temp1.right ==null){
                    temp1.right = temp2.right;
                }
            }
            if(temp1.left != null && temp2.left != null){
                stack.push(temp2.left);
                stack.push(temp1.left);
            }else{
                if(temp1.left ==null){
                    temp1.left = temp2.left;
                }
            }

        }
        return root1;

    }
}

3.LeetCode 700.二叉搜索数中的搜索

题目链接:力扣链接

参考资料代码随想录

视频讲解:B站视频讲解

给定二叉搜索树(BST)的根节点 root 和一个整数值 val

你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。

示例 1:

输入:root = [4,2,7,1,3], val = 2
输出:[2,1,3]

 思路一:递归法:

二叉搜索树是一个有序树:

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉搜索树

这就决定了,二叉搜索树,递归遍历和迭代遍历和普通二叉树都不一样

这道题,我们要进行后续遍历:是左,右,中,1要小于2,2要小于3,3要小于根节点4,如果不满足,那就return null;

遍历三大要素:

1.传参和返回值:返回treenode,传参是root和val值;

2.确定终止条件:当root为空或者root.val == val return root;

3.单边递归条件:采用前序遍历,中,左,右的一个遍历规则;找到了就立即返回,不在接着走后续。

java代码如下:

如果left不为空,那就说明左节点已经找到了和目标值一样的数据,此时,不用接着走了,我们返回left即可,如果没找到,那我们就遍历右节点,如果找到了,right就不为空,反之为空,我们返回即可。

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root == null){
            return root;
        }
        if(root.val == val){
            return root;
        }
        TreeNode left = searchBST(root.left,val);
        if(left != null){
            return  left;
        }
        TreeNode right = searchBST(root.right,val);
        return right;

    }
}

思路二:层序遍历(迭代法)

java代码如下:

我们还是走前序遍历:如果找到了temp.val ==val;我们就结束循环,反之,便利了整个二叉树,都没有找到,那就返回null;

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if (root == null) {
            return root;
        }
        if (root.val == val) {
            return root;
        }
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while (!stack.isEmpty()) {
            int size = stack.size();
            while (size > 0) {
                TreeNode temp = stack.pop();
                if (temp.val == val) {
                    return temp;
                }
                if (temp.right != null) {
                    stack.push(temp.right);
                }
                if (temp.left != null) {
                    stack.push(temp.left);
                }
                size--;
            }
        }
        return null;
    }

}

 

4.LeetCode 98.验证搜索二叉树

题目链接:力扣链接

参考资料代码随想录

视频讲解:B站视频讲解

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:root = [2,1,3]
输出:true

思路:

二叉搜索树是一个有序树:

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉搜索树

这就决定了,二叉搜索树,递归遍历和迭代遍历和普通二叉树都不一样

这道题,我们要进行中续遍历:是左,中,右

递归法:

1.确定传参和返回值:传参是root,返回值是boolean类型

2.终止条件:按照后续遍历,如果某个值比下一个遍历的值要大,那就return false;

3.单边递归条件:root.left和root.right,因为有返回值,所以需要接受返回值

class Solution {
    // 定义一个前节点,默认为null
    TreeNode max;
    public boolean isValidBST(TreeNode root) {
        if(root == null){
            return true;
        }
        //左,如果左边已经不满足了,则直接返回false;
        boolean left = isValidBST(root.left);

        // 接下来的遍历,判断是不是比前面一个节点的数值要打,如果大就正确,如果小就返回false
        if(max != null && max.val >= root.val){
            return false;
        }
        // 第一次遍历,我们要将root的值赋值给max;
        max =root;
        // 右
        boolean right =  isValidBST(root.right);
        return  left && right;

    }
}

 思路二:迭代法

java代码如下:

class Solution {
    // 迭代
    public boolean isValidBST(TreeNode root) {
        if (root == null) {
            return true;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode pre = null;
        while (root != null || !stack.isEmpty()) {
            while (root != null) {
                stack.push(root);
                root = root.left;// 左
            }
            // 中,处理
            TreeNode pop = stack.pop();
            if (pre != null && pop.val <= pre.val) {
                return false;
            }
            pre = pop;

            root = pop.right;// 右
        }
        return true;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值