572. 另一棵树的子树
题目来源
LeetCode: 572. 另一棵树的子树
面试题 04.10. 检查子树
题目分析
题目难度
简单
题目标签
树、深度优先搜索、二叉树
题目限制
- 二叉树中节点的数目范围是
[1, 2000]
- 节点的值在
[-10^4, 10^4]
范围内
解题思路
我们需要判断一棵二叉树 root
是否包含另一棵二叉树 subRoot
作为其子树。可以通过深度优先搜索(DFS)来遍历 root
,并在每个节点处检查是否与 subRoot
相同。
核心算法步骤
- 从
root
的根节点开始,递归地检查每个节点。 - 对于每个节点,使用
isSame
方法检查它是否与subRoot
相同。 - 如果当前节点与
subRoot
相同,返回true
。 - 如果当前节点不同,递归地检查其左右子节点。
代码实现
public class Solution {
public boolean isSubtree(TreeNode<Integer> root, TreeNode<Integer> subRoot) {
if (subRoot == null) {
return true;
}
if (root == null) {
return false;
}
if (isSame(root, subRoot)) {
return true;
}
return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);
}
private boolean isSame(TreeNode<Integer> root, TreeNode<Integer> subRoot) {
if (root == null || subRoot == null) {
return root == subRoot;
}
if (!root.val.equals(subRoot.val) || getHeight(root) != getHeight(subRoot)) {
return false;
}
return isSame(root.left, subRoot.left) && isSame(root.right, subRoot.right);
}
private int getHeight(TreeNode<Integer> root) {
if (root == null) {
return 0;
}
return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
}
}
代码解读
isSubtree
方法从root
的根节点开始递归地检查是否包含subRoot
。isSame
方法用于递归地检查两棵树是否完全相同。getHeight
方法用于获取树的高度,用于辅助比较两棵树是否相同。
性能分析
- 时间复杂度:O(n * m),其中 n 是
root
的节点数,m 是subRoot
的节点数。最坏情况下,我们需要检查root
的每个节点与subRoot
是否相同。 - 空间复杂度:O(h),其中 h 是
root
的高度,这是由于递归调用栈的深度。
测试用例
public static void main(String[] args) {
TreeNode<Integer> root = new TreeNode<>(3);
root.left = new TreeNode<>(4);
root.right = new TreeNode<>(5);
root.left.left = new TreeNode<>(1);
root.left.right = new TreeNode<>(2);
TreeNode<Integer> subRoot = new TreeNode<>(4);
subRoot.left = new TreeNode<>(1);
subRoot.right = new TreeNode<>(2);
Solution solution = new Solution();
boolean result = solution.isSubtree(root, subRoot);
System.out.println(result); // 输出: true
}
扩展讨论
- 其他方法:可以使用序列化二叉树的方法,然后使用字符串匹配算法(如 KMP)来检查
subRoot
是否为root
的子串。
总结
通过深度优先搜索,我们可以有效地解决这个问题。在实现过程中,需要注意递归的终止条件和边界情况的处理。这个问题不仅考察了对二叉树的理解,还考察了递归算法的设计能力。希望这篇技术博客能够帮助你更好地理解和解决572. 另一棵树的子树”这个问题。