Subtree of Another Tree

问题描述

判断一颗二叉树t是否是一颗二叉树s的 子树.

分析:

这种题目属于对二叉树的结构进行判断和操作的题目。注意题目说明的是判断子树问题,而不是子结构问题,也不是判断 同一颗二叉树问题.
子树—–>子结构
同一颗二叉树—–>子树——>子结构

解法一:

Code:

public class Solution {
    public boolean isSubtree(TreeNode s, TreeNode t) {
        if (t == null){
            return true;
        }
        if (s == null) {
            return false;
        }
        if (areIdentical(s, t)){
            return true;
        }
        return isSubtree(s.left, t) || isSubtree(s.right, t);
    }
    private boolean areIdentical(TreeNode root1, TreeNode root2){
        if (root1 == null && root2 == null){
            return true;
        }
        if (root1 == null || root2 == null){
            return false;
        }
        if (root1.val != root2.val){
            return false;
        }
        return areIdentical(root1.left, root2.left) && areIdentical(root1.right, root2.right);
    }
}

思路:

辅助函数areIdentical()用来判断两个二叉树是否为同一颗二叉树,原问题中,如果二叉树s和t为同一颗树,则必为子树,否则就继续递归判断t是否为左子树或者右子树的子树。

解法二:

思路:

利用二叉树遍历的唯一性来求解,不妨选用中序遍历,如果序列化后得到的字符串t为字符串s的子串,则t为s的子树。
这里要注意的一点是,将空结点也要序列化为某个字符,否则就为判断子结构而不一定是子树了。

Code:

public class Solution {
    public boolean isSubtree(TreeNode s, TreeNode t) {
        return serialize(s).contains(serialize(t));
    }
    private String serialize(TreeNode root) {
        StringBuilder res = new StringBuilder();
        serialize(root, res);
        return res.toString();
    }
    private void serialize(TreeNode curr, StringBuilder res){
        if (curr == null){
            res.append("$");
            return;
        }
        res.append(curr.val);
        serialize(curr.left, res);
        serialize(curr.right, res);

    }
}

注意:

方法二若不对空树序列化就会得到子结构问题,而不是子树问题。
另外这里调用的是jdk的String.contains(),最佳实现可能是KMP。
其实也就是strstr算法(basic or rabin karp or KMP)…

这里用前序和后序遍历序列化都可以,但是中序遍历序列化不行。

已知某个二叉树的(前序 || 后序) && 中序 可以唯一确定一颗二叉树

参考

http://www.geeksforgeeks.org/check-binary-tree-subtree-another-binary-tree-set-2/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值