代码随想录算法训练营第20天|● 654.最大二叉树 ● 617.合并二叉树 ● 700.二叉搜索树中的搜索 ● 98.验证二叉搜索树

● 654.最大二叉树

文字
视频
题目

1.思路

构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。
递归三部曲:
一:确定递归函数的参数和返回值
为了减小空间复杂度,即每次递归切割数组时都需要新建数组,我直接使用了数组下标进行了对数组的切割。函数参数是存放元素的数组,数组起点,数组终点。
二:确认中止条件
如果传入的是空数组,返回null;
如果传入的数组只有一个元素,则直接创建返回该节点,不进行递归操作。
三:确认单层递归逻辑
先找到数组里的最大值,创造节点,然后分割,递归。

2.代码实现

class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return tranversal(nums,0,nums.length-1);

    }
    public TreeNode tranversal(int[] nums,int begin, int end){
        if(begin>end)//这个数组元素为0
            return null;
        if(begin == end){//这个数组元素个数为1
            return new TreeNode(nums[begin]);
        }
        int maxValue=0;
        int index=0;
        for(int i=begin;i<=end;i++){
            if(nums[i]>maxValue){
                maxValue=nums[i];
                index=i;
            }
        }
        TreeNode temp= new TreeNode(maxValue);
        temp.left=tranversal(nums,begin,index-1);
        temp.right=tranversal(nums,index+1,end);
        return temp;
    }
}

● 617.合并二叉树

文字
视频
题目

1.思路

方法一:递归
本题使用哪种遍历都是可以的!

1.确定递归函数的参数和返回值:
首先要合入两个二叉树,那么参数至少是要传入两个二叉树的根节点,返回值就是合并之后二叉树的根节点。
2.确定终止条件:
因为是传入了两个树,那么就有两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了(如果t2也为NULL也无所谓,合并之后就是NULL)。
反过来如果t2 == NULL,那么两个数合并就是t1(如果t1也为NULL也无所谓,合并之后就是NULL)。
3.确定单层递归的逻辑:
单层递归的逻辑就比较好写了,这里我们重复利用一下t1这个树,t1就是合并之后树的根节点(就是修改了原来树的结构)。
那么单层递归中,就要把两棵树的元素加到一起。
接下来t1 的左子树是:合并 t1左子树 t2左子树之后的左子树。
t1 的右子树:是 合并 t1右子树 t2右子树之后的右子树。
最终t1就是合并之后的根节点。

方法二:迭代法/层序遍历
用队列实现,没写

2.代码实现

递归
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;
    }
}

● 700.二叉搜索树中的搜索

文字
视频
题目

1.思路

因为二叉搜索树的有序性,遍历的时候要比普通二叉树简单很多。
方法一:递归法

二叉搜索树是一个有序树:
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树也分别为二叉搜索树
这就决定了,二叉搜索树,递归遍历和迭代遍历和普通二叉树都不一样。

1.确定递归函数的参数和返回值
递归函数的参数传入的就是根节点和要搜索的数值,返回的就是以这个搜索数值所在的节点。
2.确定终止条件
如果root为空,或者找到这个数值了,就返回root节点。
3.确定单层递归的逻辑
看看二叉搜索树的单层递归逻辑有何不同。
因为二叉搜索树的节点是有序的,所以可以有方向的去搜索。
如果root->val > val,搜索左子树,如果root->val < val,就搜索右子树,最后如果都没有搜索到,就返回NULL。
方法二:迭代法
因为二叉搜索树的特殊性,也就是节点的有序性,可以不使用辅助栈或者队列就可以写出迭代法。对于一般二叉树,递归过程中还有回溯的过程,例如走一个左方向的分支走到头了,那么要调头,在走右分支。

而对于二叉搜索树,不需要回溯的过程,因为节点的有序性就帮我们确定了搜索的方向。

2.代码实现

递归
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root==null||root.val==val)
            return root;
        TreeNode temp=null;
        if(root.val>val)
        {
            temp=searchBST(root.left,val);

        }
        else if(root.val<val)
        {
            temp=searchBST(root.right,val);    
        }
        return temp;

    }
}
迭代法
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        while(root!=null){
            if(root.val>val)
                root=root.left;
            else if(root.val<val)
                root=root.right;
            else
                return root;
        }
        return null;
    }
}

● 98.验证二叉搜索树

文字
视频
题目

1.思路

首先一定要知道二叉搜索树的特性:
要知道中序遍历下,输出的二叉搜索树节点的数值是有序序列。
有了这个特性,验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。
方法一:递归
可以遍历成一个数组,然后判断数组是否有序。
更简洁的办法是在递归遍历的时候直接判断。
这道题目比较容易陷入两个陷阱:
1.不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了。我们要比较的是 左子树所有节点小于中间节点,右子树所有节点大于中间节点。
在这里插入图片描述
陷阱2
样例中最小节点 可能是int的最小值,如果这样使用最小的int来比较也是不行的。
此时可以初始化比较元素为longlong的最小值。
问题可以进一步演进:如果样例中根节点的val 可能是longlong的最小值 又要怎么办呢?

**所以!!**用双指针来比较,一个指针pre指向前一个结点,后一个指针指向本结点
方法二:迭代法
看不懂

2.代码实现

class Solution {
    TreeNode pre=null;
    public boolean isValidBST(TreeNode root) {
        if(root==null)
            return true;
        boolean left1=isValidBST(root.left);
        if(pre!=null && pre.val>=root.val)
            return false;
        pre=root;
        boolean right1=isValidBST(root.right);
        return left1&&right1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值