二叉搜索树

654.最大二叉树

题目链接/文章讲解:https://programmercarl.com/0654.%E6%9C%80%E5%A4%A7%E4%BA%8C%E5%8F%89%E6%A0%91.html

视频讲解:https://www.bilibili.com/video/BV1MG411G7ox

思路:

  • 如果数组中只有一个元素,那么就直接创建节点返回
  • 找到数组区间内的最大值及其下标
  • 根据下标对数组进行切割左右区间
class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return constTree(nums,0,nums.length);
    }
	// 返回值:因为要构造二叉树,所以要创建节点并且返回
    // 参数:数组+起始和结束索引,也可单传一个数组这样就必须在原数组上切割可能会更加耗时
    public TreeNode constTree(int[] nums,int start,int end){
        // 终止条件
        if(end - start < 1) return null;
        if(end - start == 1){
            return new TreeNode(nums[start]);
        }

        // 找到最大值和下标
        int maxVal = 0;
        int maxIndex = 0;
        for(int i=start; i<end; i++){
            if(nums[i] > maxVal){
                maxVal = nums[i];
                maxIndex = i;
            }
        }

        // 创建节点
        TreeNode root = new TreeNode(maxVal);
        // 查找左区间(同时保证左闭右开 或 左闭右闭)
        root.left = constTree(nums,start,maxIndex);
        // 查找右区间
        root.right = constTree(nums,maxIndex+1,end);
        return root;
    }
}

617.合并二叉树

题目链接/文章讲解:https://programmercarl.com/0617.%E5%90%88%E5%B9%B6%E4%BA%8C%E5%8F%89%E6%A0%91.html

视频讲解:https://www.bilibili.com/video/BV1m14y1Y7JK

思路:

  • 两个二叉树同时进行遍历
  • 遇到如果root1的左节点为空,那么就直接返回root2,root2同理
  • 否则就合并两个二叉树的值
// 递归法
class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        // 这里已经包括两两个同时为空的情况
        // 例如r1=null,r2=null,那么直接return r2,还是返回的Null
        if(root1 == null) return root2;
        if(root2 == null) return root1;
        // 直接在root1上进行合并
        root1.val += root2.val;  // 中
        // 两个二叉树同时进行遍历
        root1.left = mergeTrees(root1.left,root2.left); // 左
        root1.right = mergeTrees(root1.right,root2.right); // 右
        return root1;
    }
}
// 使用栈迭代
class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1 == null) return root2;
        if(root2 == null) return root1;

        Stack<TreeNode> stack = new Stack<>();
        // 注意一定是root2先入栈,后面入栈的操作同理
        // 因为是在root1上进行合并
        stack.push(root2);
        stack.push(root1);

        while(!stack.empty()){
            TreeNode node1 = stack.pop(); // root1
            TreeNode node2 = stack.pop(); // root2
            // 直接合并在root1上
            node1.val += node2.val;
            if(node1.left!=null && node2.left!=null){
                stack.push(node2.left);
                stack.push(node1.left);
            }else{
                // 如果node1.left为空,就node2.left合并在node1上
                // node2.left为空的话,就表示node1.left有值,就不需要处理,因为最终结果是合并在root1上
                if(node1.left == null){
                    node1.left = node2.left;
                }
            }
            if(node1.right!=null && node2.right!=null){
                stack.push(node2.right);
                stack.push(node1.right);
            }else{
                if(node1.right == null){
                    node1.right = node2.right;
                }
            }
        }
        return root1;
    }
}

700.二叉搜索树中的搜索

题目链接/文章讲解: https://programmercarl.com/0700.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E6%90%9C%E7%B4%A2.html

视频讲解:https://www.bilibili.com/video/BV1wG411g7sF

二叉搜索树的特性:

  1. 左子树一定小于根节点,右子树一定大于根节点
  2. 使用中序遍历一定是递增的数组

思路:利用二叉搜索树的特性就可以非常简单的完成本题

  • 如果目标值小于当前节点的值,就向左遍历,否则向右遍历
  • 相等直接返回
// 递归法
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root == null) return null;

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

// 迭代法
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root == null) return null;

        while(root != null){
            if(val > root.val) root = root.right;
            else if(val < root.val) root = root.left;
            else return root;
        }
        return null;
    }
}

98.验证二叉搜索树

题目链接/文章讲解:https://programmercarl.com/0098.%E9%AA%8C%E8%AF%81%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91.html

视频讲解:https://www.bilibili.com/video/BV18P411n7Q4

利用二叉搜索树中序遍历的特性:二叉搜索树的中序遍历一定是递增的

不断判断前一个节点是否小于当前节点

class Solution {
    // 用来记录当前节点的前一个节点
    TreeNode per=null;
    public boolean isValidBST(TreeNode root) {
        // 如果是一个空树,也算是二叉搜索树
        if(root == null) return true;

        boolean left = isValidBST(root.left); // 左
        
        if(per!=null && per.val>=root.val){ // 中
            return false;
        }
        // 1.最开始per=null,所以per一定会等于最后一个节点
        // 然后在回退的过程中per就一直指向root的前一个节点
        per = root;
        boolean right = isValidBST(root.right); // 右
        return left && right;
    }
}
// 也可以先利用中序遍历将二叉树搜索树存入数组中,在判断数组的前一个元素是否小于当前元素
// 这个方法会更耗时和空间
class Solution {
    public boolean isValidBST(TreeNode root) {
        // 存储中序遍历后的二叉树搜索树
        List<Integer> res = new ArrayList<>();
        isBst(root,res);
        // 判断数组是否递增
        for(int i=1; i<res.size(); i++){
            if(res.get(i-1) >= res.get(i)) return false;
        }
        return true;

    }

    public void isBst(TreeNode root, List<Integer> res){
        if(root == null) return ;
		// 中序遍历
        isBst(root.left,res);
        res.add(root.val);
        isBst(root.right,res);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值