剑指offer 26.27.28 搜索与回溯算法(简单) 二叉树的DFS

26.

题目:

剑指 Offer 26. 树的子结构https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/

想法:首先在A中查找B的根节点,若找到则从此时起对比AB,否则返回false.

        注意B==null时,不是任何树的子结构,可优先判断.

涉及两个递归:

递归一 findBsRoot

  1. 函数作用? 在A中查找B的根节点
    输入:TreeNode A, TreeNode B
    返回值:无
  2. 递归的终止条件?
    A==null(查找完A) 或 flag==true(已经找到)
  3. 本层递归与下一层的关系
    若A.val==B.val,即已找到B的根节点,则调用第二个递归判断从此时开始A是否包含B
    否则递归遍历A的左孩子/A的右孩子和B,以在A中寻找B.

递归二 compare

  1. 函数作用? 判断B是否为A的子结构
    输入:TreeNode A, TreeNode B
    返回值:是则返回true,否则返回false
  2. 递归的终止条件?
    B==null 说明B先遍历完,即A中包含B
    A==null 说明A先遍历完,即A中不包含B
  3. 本层递归与下一层的关系
    本层需判断A.val==B.val是否成立,然后调用A.B的左孩子/A.B的右孩子
    注意:每层的返回值应与上一层的作与运算,即全部相同才为子结构

代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
//法一:
class Solution {
    boolean flag=false;
    public boolean isSubStructure(TreeNode A, TreeNode B) {
        //注意B==null时,不是任何树的子结构,可优先判断.
        if(B==null) return false;
        findBsRoot(A,B);
        return flag;
    }

    //在A中查找B的根节点
    void findBsRoot(TreeNode A, TreeNode B){
        //flag为true时,说明已经找到子结构,结束遍历
        if(A==null||flag)
            return;
        if(A.val==B.val)
            //找到根节点,继续比较子节点,判断B是否为A的子结构
            flag=compare(A,B);
        findBsRoot(A.left,B);
        findBsRoot(A.right,B);
    }

    //检查B是不是A的子结构
    boolean compare(TreeNode A, TreeNode B){
        //注意先判断B是否为空
        if(B==null)
            return true;
        //后判断A是否为空
        if(A==null)
            return false;
        //检查A.val是否等于B.val,并且递归检查A和B的左右子树
        return A.val==B.val && compare(A.left,B.left) && compare(A.right,B.right);
    }
}
//法二:不设flag也能写
class Solution {
    public boolean isSubStructure(TreeNode A, TreeNode B) {
        if(A==null||B==null) //空树不是任意一个树的子结构 空树也没有子结构
            return false;
        else //A和B为起点开始比较 或者A的左右孩子和B为起点开始比较
           return judge(A,B) || isSubStructure(A.left,B) || isSubStructure(A.right,B);
    }

    //依次对比每个节点,判断B是不是A的子结构
    public boolean judge(TreeNode A, TreeNode B) {
        //如果B先遍历完 说明B是A的子结构
        if(B == null) return true;
        //如果A先遍历完或者AB节点的值不一样了 说明B不是A的子结构
        if(A == null || A.val != B.val) return false;
        //依次对比左右孩子
        return judge(A.left, B.left) && judge(A.right, B.right);
    }
}

结果:

27.

题目:

剑指 Offer 27. 二叉树的镜像https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/

 

 

想法:依次交换所有节点的左右节点即可

递归 recursion

  1. 函数作用? 交换root节点的所有左右孩子
    输入:TreeNode root
    返回值:无
  2. 递归的终止条件?
    root==null(遍历完root)
  3. 本层递归与下一层的关系
    先序遍历
    交换此节点的左右孩子,再递归遍历其左孩子和右孩子

代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
//代码一:
class Solution {
    public TreeNode mirrorTree(TreeNode root) {
        //首先判断是否有根节点,可以省去后续步骤
        recursion(root);
        return root;
    }
    void recursion(TreeNode root){
        if(root==null){
            return;
        }
        TreeNode tmp=root.left;
        root.left=root.right;
        root.right=tmp;
        recursion(root.left);
        recursion(root.right);
    }
}

参考他人发现可以直接在递归中返回节点
代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
//代码二:
class Solution {
    public TreeNode mirrorTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        TreeNode leftRoot = mirrorTree(root.right);
        TreeNode rightRoot = mirrorTree(root.left);
        root.left = leftRoot;
        root.right = rightRoot;
        return root;
    }
}

结果:

28.

题目:

剑指 Offer 28. 对称的二叉树https://leetcode-cn.com/problems/dui-cheng-de-er-cha-shu-lcof/

想法: 

递归二 compare

  1. 函数作用? 判断传入的两个树L.R是否镜像
    输入:TreeNode L, TreeNode R
    返回值:是则返回true,否则返回false
  2. 递归的终止条件?
    L==null 且 R==null  -> 到底了都长得一样 -> 镜像
    L==null.R!=null 或 L!=null.R==null  -> 说明左右长得不一样 -> 非镜像
    L.val!=R.val 节点值不相等 -> 长得不一样 -> 非镜像
  3. 本层递归与下一层的关系
    判断完本层节点,需判断L树的左孩子与R树的右孩子是否一样

注意:空树必为镜像,可先进行判断

代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

class Solution {
    public boolean isSymmetric(TreeNode root) {
        return root == null ? true : recur(root.left, root.right);
    }
    boolean recur(TreeNode L, TreeNode R) {
        if(L == null && R == null) 
            return true;
        if(L == null || R == null || L.val != R.val) 
            return false;
        return recur(L.left, R.right) && recur(L.right, R.left);
    }
}

结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值