代码随想录算法训练营第二十天 _ 二叉树_654.最大二叉树 、617.合并二叉树 、700.二叉搜索树中的搜索、98.验证二叉搜索树。

学习目标:

60天训练营打卡计划!


耶耶耶耶!已经过了1/3啦!
栈用于模拟递归调用的状态,实现深度优先遍历,而队列用于按层级顺序遍历,实现广度优先遍历。

学习内容:

654.最大二叉树

  • 使用递归法,思路比较清晰。
  • 一定要认真看明白题目的要求,再根据题目构造就会变得很清晰。
class Solution {
    // 获取子数组中的最大值的位置
    private int getMax(int[] nums, int start, int end) {
        int index = start;
        int max = nums[start];
        for(int i = start; i < end; i++){
            if(nums[i] > max){
                max = nums[i];
                index = i;
            }
        }
        return index;
    }

    private TreeNode constructHelper(int[] nums, int start, int end) {
        if(end == 0 || end - start == 0)  return null;
        int max_index = getMax(nums, start, end);
        TreeNode root = new TreeNode(nums[max_index]);
        if(end - start == 1)  return root;
        // 构造左子树
        if(start < max_index) 
            root.left = constructHelper(nums, start, max_index);
        // 构造右子树
        if(end - 1 > max_index) 
            root.right = constructHelper(nums, max_index + 1, end);
        return root;
    }

    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return constructHelper(nums, 0, nums.length);
    }
}

617.合并二叉树

  • 一起操作两个二叉树(n1 n2)
    • 结束条件是:当n1为空时,返回n2;同理。
      处理过程:两个节点都有值时,相加并存储(中)。
      对于左右子节点则直接递归函数。
  • 迭代法:
    • 最重要的思想—不需要新建一棵树,在原有的树的基础上进行操作即可,因为que队列只是存了二叉树节点的引用,并不会破坏原有的二叉树的结构。
    • 迭代法通过循环和条件判断来逐个处理数据结构中的元素
  • 递归法:
    • 可以新建树,也可以在原树的基础上继续操作。
      难点是如何同时操作两个树?或者说同时操作两棵树表现在什么地方?
class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        Queue<TreeNode> que = new LinkedList<>();
        int size = -1;
        if(root1 == null && root2 == null) return null;
        if(root1 == null && root2 != null) return root2;
        if(root1 != null && root2 == null) return root1;

        que.add(root1);
        que.add(root2);
        while(!que.isEmpty()){
            TreeNode node1 = que.remove();
            TreeNode node2 = que.remove();
            // add()函数存的是引用值,所以修改node1其实就是在修改root1
            // 共有的部分因为要做求和操作,故要加入队列。
            node1.val += node2.val;

            if(node1.left != null && node2.left != null){
                que.add(node1.left);
                que.add(node2.left);
            }

            if(node1.right != null && node2.right != null){
                que.add(node1.right);
                que.add(node2.right);
            }
            
            // 直接将root2中的子树继承
            if(node1.left == null && node2.left != null)
                node1.left = node2.left;

            if(node1.right == null && node2.right != null)
                node1.right = node2.right;
            
        }
        return root1;
    }
}

// 递归
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.二叉搜索树中的搜索

  • 迭代法:借助二叉搜索树的搜索规则,使得迭代法变得异常的简单。
  • 递归法:结束条件有两个,只需要对左右子树操作即可。

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 root;
    }
}


class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        TreeNode node = new TreeNode(0);
        if(root == null || val == root.val)  return root;

        if(val < root.val)  node = searchBST(root.left, val);
        if(val > root.val)  node = searchBST(root.right, val);

        return node;
    }
}

98.验证二叉搜索树

  • 递归法:使用中序遍历,对于二叉搜索树来说,中序遍历得到的结果是有顺序的。

class Solution {
    // 如果放到递归里,每次的节点都会和-Integer.MAX_VALUE做对比,那么一定是true
    private long max = -Long.MAX_VALUE;
    public boolean isValidBST(TreeNode root) {
        if(root == null) return true;

        // 使用中序遍历
        boolean left = isValidBST(root.left);

        if(root.val <= max)  return false;
        max = root.val;

        boolean right = isValidBST(root.right);
        return right && left;
    }
}

class Solution {
    // 如果放到递归里,每次的节点都会和-Integer.MAX_VALUE做对比,那么一定是true
    // private long max = -Long.MAX_VALUE;
    // 双指针法
    TreeNode pre = null;
    public boolean isValidBST(TreeNode root) {
        if(root == null) return true;

        // 使用中序遍历
        boolean left = isValidBST(root.left);

        if(pre != null && pre.val >= root.val)  return false;
        pre = root;

        boolean right = isValidBST(root.right);
        return right && left;
    }
}

学习时间:

  • 上午一小时,下午两个小时,整理文档半小时。
  • 2024.2.21 二刷
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值