夸父追日:第六章 二叉树 part02

今日收获(优先掌握递归法):翻转二叉树,对称二叉树,求最大/最小深度

1. 翻转二叉树

题目链接:226. - 力扣(LeetCode)

思路:递归函数的作用是交换两个节点的左右子树。如果当前节点为空则返回,交换完当前节点后再递归调用传入左右节点

方法:

class Solution {
    public TreeNode invertTree(TreeNode root) {
        swapNode(root);
        return root;
    }

    // 重复交换节点的左右子树
    public void swapNode(TreeNode node){
        if (node==null){  // 终止条件
            return;
        }

        // 当前节点
        TreeNode temp=node.left;
        node.left=node.right;
        node.right=temp;

        swapNode(node.left);
        swapNode(node.right);
    }
}

总结:利用递归法首先要思考递归函数的作用,在整个过程中重复的操作有哪些,将这些重复操作抽取成一个函数。然后再考虑递归的终止条件,当前节点的处理,递归调用自身。

2. 对称二叉树

题目链接:101. - 力扣(LeetCode)

思路:先判断当前两个节点是否相等,再判断左左右右和左右右左的情况。注意两个节点值相等还需要进一步递归判断。

方法:

class Solution {
    public boolean isSymmetric(TreeNode root) {
        if (root==null){
            return true;
        }
        return both(root.left,root.right);
    }

    // 判断两个节点的外侧节点和内侧节点是否对称
    public boolean both(TreeNode left,TreeNode right){
        if (left==null&&right==null){
            return true;
        }

        if (left!=null&&right==null){
            return false;
        }

        if (left==null&&right!=null){
            return false;
        }

        if (left.val!=right.val){
            return false;
        }

        // 两个结点都不为空且值相等,需要进一步判断
        return both(left.left,right.right)&&both(left.right,right.left);  // 子树的外侧和里侧都要对称
    }
}

相似题目:

(1)100. 相同的树- 力扣(LeetCode)

 思路:和对称二叉树思路类似,先判断当前两个节点是否相等,如果值相等再递归判断左左和右右的情况

class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p==null&&q==null){
            return true;
        }

        if (p!=null&&q==null){
            return false;
        }

        if (p==null&&q!=null){
            return false;
        }

        if (p.val!=q.val){
            return false;
        }

        return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
    }
}

(2)572. 另一个树的子树- 力扣(LeetCode)

思路:首先判断当前子树是否和模式树相等,再判断左子树和右子树是否和模式串分别相等

class Solution {
    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        if (isSameTree(root,subRoot)){
            return true;
        }

        boolean left=false;
        boolean right=false;
        if (root.left!=null){
            left=isSubtree(root.left,subRoot);
        }

        if (root.right!=null){
            right=isSubtree(root.right,subRoot);
        }

        return left||right;
    }

    public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p==null&&q==null){
            return true;
        }

        if (p!=null&&q==null){
            return false;
        }

        if (p==null&&q!=null){
            return false;
        }

        if (p.val!=q.val){
            return false;
        }

        return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
    }
}

 总结:迭中迭,迭麻了

3. 求最大深度

题目链接:101. - 力扣(LeetCode)

思路:可以用层序迭代遍历判断循环的次数。也可以使用递归函数求传入结点的高度,当前节点的高度是左右子树的高度最大值再加1,叶子节点的高度为0

方法:

class Solution {
    public int maxDepth(TreeNode root) {
        return maxHeight(root);
    }

    public int maxHeight(TreeNode root) {
        if (root==null){  // 叶子节点高度为0
            return 0;
        }

        // 左右子树的高度最大值再加1
        return Math.max(maxHeight(root.left),maxHeight(root.right))+1;
    }
}

总结:高度是叶子节点到根节点的长度,从下往上;深度是根节点到根节点的长度,从上往下。

叶子节点到根节点的高度和深度相等

相似题目:

559.n叉树的最大深度

思路:求子树的高度最大值再加1

总结:三元运算符不如Math.max高效,用?:会超出时间限制

4. 求最小深度

题目链接:111. - 力扣(LeetCode)

思路:可以用层序迭代遍历;用递归时仍然是求叶子节点的高度来代替深度。注意深度是根节点到叶子节点的距离,所以要额外处理根节点的左右子树为空的情况

方法:

class Solution {
    public int minDepth(TreeNode root) {
        // 叶子节点
        if (root==null){
            return 0;
        }

        // 左子树为空
        if (root.left==null&&root.right!=null){
            return 1+minDepth(root.right);
        }

         // 右子树为空
        if (root.right==null&&root.left!=null){
            return 1+minDepth(root.left);
        }

        // 左右子树都不为空
        return 1+Math.min(minDepth(root.right),minDepth(root.left));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值