【剑指offer】26. 树的子结构

262 阅读2分钟

题目描述

在这里插入图片描述 在这里插入图片描述

// 26. 树的子结构

// 力扣
// 输入两棵二叉树AB,判断B是不是A的子结构。(约定
// 空树不是任意一个树的子结构)

// BA的子结构, 即 A中有出现和B相同的结构和节点值。


// 牛客
// 输入两棵二叉树AB,判断B是不是A的子结构。(ps:我们
// 约定空树不是任意一个树的子结构)

题解

// 力扣
// 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
// 内存消耗:39.9 MB, 在所有 Java 提交中击败了95.56%的用户
class Solution {
	// 解题函数:作用是寻找B树是否是A树的子树(A树是否包含B)
	public boolean isSubStructure(TreeNode A, TreeNode B) {
		if (A == null || B == null)  // 如果其中一个为null,直接返回false
			return false;
		boolean res = false;
		// 如果A和B根结点相同,调用recur函数判断之后的遍历AB两树是否相同
		if (A.val == B.val)  
			res = recur(A, B);  // 遍历结果返回为res
		if (!res)  // 如果没找出子树结构
			// 递归调用解题函数,输入A.left:判断A左子树是否包含B
			res = isSubStructure(A.left, B);  
		if (!res)
			// 递归调用解题函数,输入A.right:判断A右子树是否包含B
			res = isSubStructure(A.right, B);
		return res;
	}
	
	// 前序遍历的判断函数:从当前输入结点A和B开始,以前序遍历顺序
	// 逐节点判断A数是不是包含B树,其中:
	// 1.B树如果被遍历完了,说明A树此前遍历的所有结点和B相同,B树为A子树
	// 2.如果A树被遍历完了,直接返回false,B树不可能是A子树
	// 3.如果出现遍历节点不相等,返回false。
	// 返回:recur(A.left,B.left) && recur(A.right, B.right);
	// 也就是先遍历完左树,再根结点,再右树,此为遵循了前序遍历的顺序。
	public boolean recur(TreeNode A, TreeNode B) {
		if (B == null) return true;
		if (A == null) return false;
		if (A.val != B.val) return false;
		// 能到达return语句,说明满足A.val==B.val了
		return recur(A.left, B.left) && recur(A.right, B.right);
	}
}


// 力扣
// 意思跟上面的是一样的,只是写法不同。
// 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
// 内存消耗:40.2 MB, 在所有 Java 提交中击败了67.07%的用户
class Solution {
	public boolean isSubStructure(TreeNode A, TreeNode B) {
		if (A == null || B == null) {
			return false;
		}
		return (recur(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B))
	}
	
	private boolean recur(TreeNode A, TreeNode B) {
		if (B == null) return true;
		if (A == null) return false;
		if (A.val != B.val) return false;
		return recur(A.left, B.left) && recur(A.right, B.right);
	}
}

// 牛客
// 运行时间:16ms
// 占用内存:9804k
public class Solution {
    public boolean HasSubtree(TreeNode root1,TreeNode root2) {
        if (root1 == null || root2 == null)
            return false;
        boolean res = false;
        if (root1.val == root2.val)
            res = recur(root1, root2);
        if (!res)
            res = HasSubtree(root1.left, root2);
        if (!res)
            res = HasSubtree(root1.right, root2);
        return res;
    }
    
    private boolean recur(TreeNode A, TreeNode B) {
        if (B == null)
            return true;
        if (A == null)
            return false;
        if (A.val != B.val)
            return false;
        return recur(A.left, B.left) && recur(A.right, B.right);
    }
}


// 牛客
// 运行时间:11ms
// 占用内存:9760k
public class Solution {
    public boolean HasSubtree(TreeNode root1,TreeNode root2) {
        if (root1 == null || root2 == null)
            return false;
        return (recur(root1, root2) || HasSubtree(root1.left, root2) || HasSubtree(root1.right, root2));
    }
    
    private boolean recur(TreeNode A, TreeNode B) {
        if (B == null)
            return true;
        if (A == null)
            return false;
        if (A.val != B.val)
            return false;
        return recur(A.left, B.left) && recur(A.right, B.right);
    }
}