算法打卡Day17(补卡)| 二叉树篇-最大二叉树、合并二叉树、二叉搜索树中的搜索、验证二叉搜索树

30 阅读2分钟

654. 最大二叉树

题目链接:leetcode.cn/problems/ma…

关键点:每次遍历找到最大值,然后将最大值左右两边分别进行左遍历和右遍历,依次类推,直到左右节点相等

class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return get(nums, 0, nums.length);
    }
​
    private TreeNode get(int[] nums, int begin, int end){
        TreeNode node = new TreeNode();
        //终止条件
//        if(begin>=end || begin>=nums.length || end < 0){
        //⏰终止条件简化版
        if(end - begin < 1){
            return null;
        }
        if(end-begin==1){
            node.val = nums[begin];
            return node;
        }
        //中间处理逻辑
        int maxValue = 0;
        int index = 0;
        for(int i = begin; i < end; i++){
            if(nums[i] > maxValue){
                maxValue = nums[i];
                index = i;
            }
        }
        node.val = maxValue;
        //左
        node.left = get(nums, begin, index);
        //右
        node.right = get(nums, index+1, end);
        return node;
    }
}

617. 合并二叉树

题目链接:leetcode.cn/problems/me…

本题要点:

  • Q:向下递归时,如果确定终止条件?即二叉树1的节点到该层结束了,但是二叉树2的节点还有延伸,该如何定义这个条件呢?

    A:链表之间的关联是指针指向,当二叉树1的节点到底了,二叉树2的节点没到底,直接返回该层二叉树2的节点,因为该节点后序的节点信息,left和right本身就随着该节点的移动而携带着

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

题目链接:leetcode.cn/problems/se…

关键点:二叉搜索树的特性,左边所有节点都比根节点小,右边所有节点都比根节点大

  • 递归法
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root==null ||root.val==val) return root;
        TreeNode node = new TreeNode();
        if(root.val>val){
           node = searchBST(root.left, val); 
        }
        if(root.val<val){
           node = searchBST(root.right, val);
        }
        return node;
    }
}
  • 迭代法
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. 验证二叉搜索树(mmhh)

题目链接:leetcode.cn/problems/va…

本题要点:

  • 不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了

    • ❌root.left.val<=root.val&&root.right.val>=root.val
  • 我们要比较的是 左子树所有节点小于中间节点,右子树所有节点大于中间节点

    • 中序-左中右遍历,每次使用指针将上一个节点保存起来,然后作比较
class Solution {
    private 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;
        }else{
            pre = root;
        }
        boolean right = isValidBST(root.right);
        return left&&right;
    }
}

递归函数何时有返回值?

  • 如果需要搜索整棵二叉树且不用处理递归返回值,递归函数就不要返回值。(这种情况113.路径总和ii)
  • 如果需要搜索整棵二叉树且需要处理递归返回值,递归函数就需要返回值。 (这种情况我们在236. 二叉树的最近公共祖先 (opens new window)中介绍)
  • 如果要搜索其中一条符合条件的路径,那么递归一定需要返回值,因为遇到符合条件的路径了就要及时返回。