“`java
要注意有两层递归,一个是要遍历每个节点,然后在这个节点往下遍历看是否是子结构
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
if (A == null || B == null) {
return false;
}
if (isSubTree(A,B)) {
return true;
}
if (isSubStructure(A.left, B) || isSubStructure(A.right, B)) {
return true;
}
return false;
}
public boolean isSubTree(TreeNode A, TreeNode B) {
if (B == null) {
return true;
}
if (A == null || A.val != B.val) {
return false;
}
return isSubTree(A.left, B.left) && isSubTree(A.right, B.right);
}
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);
}
}
class Solution {
public:
// match B in A from A' root
bool _isSubTree(TreeNode* A, TreeNode* B) {
if (B == NULL) return true;
if (A == NULL) return false;
if (A->val == B->val)
return _isSubTree(A->left, B->left) &&
_isSubTree(A->right, B->right);
else return false;
}
// match B in A
bool isSubStructure(TreeNode* A, TreeNode* B) {
if (B == NULL || A == NULL) return false;
if (_isSubTree(A, B))
return true;
else
return isSubStructure(A->left, B) ||
isSubStructure(A->right, B);
}
};
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
if A is None or B is None:
return False
return self.check(A, B) or self.isSubStructure(A.left,B) or self.isSubStructure(A.right,B)
def check(self, A: TreeNode, B: TreeNode) -> bool:
if B is None:
return True
if not A or A.val!=B.val:
return False
return self.check(A.left, B.left) and self.check(A.right, B.right)
// 树的子结构, A 节点数 N, B 结点数 M
// 时间复杂度 O(NM)
// 空间复杂度 O(M)
class Solution {
private:
// 判断 B 是不是 A 的子树
bool isSubTree(TreeNode* A, TreeNode* B) {
if (B == nullptr) {
return true;
}
if (A == nullptr || A->val != B->val) {
return false;
}
return isSubTree(A->left, B->left) && isSubTree(A->right, B->right);
}
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
if (A == nullptr || B == nullptr) {
return false;
}
return isSubTree(A, B) || isSubStructure(A->left, B) || isSubStructure(A->right, B);
}
};
递归
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
if not A or not B:
return False
if self.is_sub(A, B):
return True
if self.isSubStructure(A.left, B) or self.isSubStructure(A.right, B):
return True
return False
def is_sub(self, A, B):
if not B:
return True
if not A:
return False
if A.val != B.val:
return False
return self.is_sub(A.left, B.left) and self.is_sub(A.right, B.right)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
# 时间复杂度:O(n * k)
class Solution:
def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:
def isSame(root, subRoot):
if not root and not subRoot:
return True
elif not root or not subRoot:
return False
return root.val == subRoot.val and isSame(root.left, subRoot.left) and isSame(root.right, subRoot.right)
if not root:
return False
if root.val == subRoot.val and isSame(root, subRoot):
return True
return self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)
//递归
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);
}
boolean recur(TreeNode A, TreeNode B) {
if (B == null) return true;
if (A == null || A.val != B.val) return false;
// A.val = B.val, 接着比较A.left&right 是否 等于B.left&right
return recur(A.left, B.left) && recur(A.right, B.right);
}
}
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
// 如果树 A 或树 B 为空,或者树 B 是空树但树 A 不是空树,则 B 不是 A 的子结构
if (A == null || B == null) {
return false;
}
// 从根节点开始递归判断树 A 中是否存在与树 B 结构相同的子树
return isSubTree(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B);
}
// 判断以节点 A 和节点 B 为根节点的两棵树是否相等
private boolean isSubTree(TreeNode A, TreeNode B) {
// 如果树 B 为空,则认为 B 是 A 的子树
if (B == null) {
return true;
}
// 如果树 A 为空,或者节点 A 和节点 B 的值不相等,则树 A 不是树 B 的子树
if (A == null || A.val != B.val) {
return false;
}
// 递归判断树 A 的左子树和树 B 的左子树是否相等,
// 以及树 A 的右子树和树 B 的右子树是否相等
return isSubTree(A.left, B.left) && isSubTree(A.right, B.right);
}
}
共以下 46 个回答
“`java
要注意有两层递归,一个是要遍历每个节点,然后在这个节点往下遍历看是否是子结构
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
if (A == null || B == null) {
return false;
}
if (isSubTree(A,B)) {
return true;
}
if (isSubStructure(A.left, B) || isSubStructure(A.right, B)) {
return true;
}
return false;
}
}
“`java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
if(A==null||B==null){
return false;
}
return is(A,B)||isSubStructure(A.left,B)||isSubStructure(A.right,B);
}
public boolean is(TreeNode A, TreeNode B){
if(B==null){
return true;
}
if(A==null){
return false;
}
if(A.val!=B.val){
return false;
}
}
二叉树优先考虑递归,先实现递归对比两个树,再实现递归对比树的左右子树和树
“`java
时间复杂度0(n)
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
if(A == null || B == null){
return false;
}
}
递归,时间复杂度O(MN),空间复杂度为O(M)。M为数A节点数,N为数B节点数
思路:递归解决
思路:递归解决
java实现
太抽象了,做这个问题的时候一开始没有把握好子问题,做的头皮发麻,但做出来了感觉还是挺好的!
时间复杂度O(mn),空间复杂度O(m)
【思路】递归,定义一个_isSubTree函数用来从根节点匹配两个子树
【复杂度】时间复杂度O(nlogn)?
C++实现
定义了一个Solution类,其中包含一个isSubStructure方法。该方法接受两个参数A和B,分别表示树A和树B的根节点。该方法的返回值是一个布尔值,表示树B是否是树A的子结构。
在isSubStructure方法中,首先判断A和B是否为空,如果其中任意一个为空,则返回False。然后,调用check方法判断A和B是否相同,如果相同则返回True。接着,递归调用isSubStructure方法判断A的左子树和B是否相同,以及A的右子树和B是否相同。最后,如果以上三种情况中有任意一种返回True,则返回True;否则返回False。
在check方法中,首先判断B是否为空,如果为空,则说明B已经遍历完了,返回True。然后,判断A是否为空,如果为空,则说明A已经遍历完了,返回False。接着,判断A的值是否等于B的值,如果不等,则返回False。最后,递归调用check方法判断A的左子节点和B的左子节点是否相同,以及A的右子节点和B的右子节点是否相同。如果以上两种情况都返回True,则返回True;否则返回False。
分两步
时间复杂度为O(MN)
空间复杂度为O(M)
时间复杂度和空间复杂度为O(M+N),M+N 为A, B 树的节点和
【时间O(n),空间O(1)】
递归
思路:构造辅助函数,用于检查是否包含子结构,然后灵活地运用,return不同的结果的或
时间复杂度O(n) 空间复杂度O(n)
public boolean isSubStructure(TreeNode A, TreeNode B) {
if(A null || B null){
return false;
}
if(isSubTree(A, B)){ //判断A和B是不是子树
return true;
}
if(isSubStructure(A.left, B) || isSubStructure(A.right, B)){
return true;
}
return false;
}
public boolean isSubTree(TreeNode TA, TreeNode TB){
if(TB null) return true; //TB为空
if(TA null) return false; //TA为空
if(TA.val != TB.val) return false;
return isSubTree(TA.left, TB.left) && isSubTree(TA.right, TB.right);
}
时间复杂度:o(n*k)
空间复杂度:o(n)
暴力
时间:O(mn)
空间:O(mmn)
他解:递归
时间:O(mn)
空间:O(m)
时间复杂度为 O(n*k)。
空间复杂度:空间复杂度为树 A 的高度
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
if (A nullptr || B nullptr)
return false;
};
时间复杂度 O(mn)
空间复杂度 O(m)
时间复杂度 O(mn)
空间复杂度 O(m)
有一点思路但写不出来,看了讲解才明白
时间复杂度为 O(n*k)。
空间复杂度:空间复杂度为树 A 的高度
c++递归
bool is_container(TreeNode* A, TreeNode* B)
{
if(BNULL)return true;
if(ANULL)return false;
if(A->valB->val)return is_container(A->left,B->left)&&is_container(A->right,B->right);
else return false;
}
bool isSubStructure(TreeNode* A, TreeNode* B) {
if(ANULL||BNULL)return false;
if(A->valB->val&&is_container(A,B))return true;
else
return isSubStructure(A->left,B)||isSubStructure(A->right,B);
}
复杂度
时间复杂度: $O(MN)$,M N 为A,B的节点数。
空间复杂度: $O(M)$ ,M为A的节点数。
Code
C++实现
class Solution {
public:
bool compare(TreeNode* C, TreeNode* B)
{
if(B NULL) return true;
if(C NULL) return false;
if(C->val B->val){
return compare(C->left,B->left) && compare(C->right,B->right);
}
else
return false;
}
bool isSubStructure(TreeNode* A, TreeNode* B)
{
if(A NULL || B NULL) return false;
if(A->val B->val)
{
if(compare(A,B))
return true;
}
return isSubStructure(A->left,B) || isSubStructure(A->right,B);
}
};
时间复杂度:O(n*k) n:A子树结点个数 k:B子树结点个数
1、分析判断要涉及左右子树判断,用递归
2、新建方法确定是否b为以a为头结点的子树,判断值相同则继续递归判断
3、最后递归左右子树判断B是否为A的子树中的一部分
时间复杂度:O(n)
空间复杂度:O(n)
这题,重点是要弄明白怎样才算是子结构。
深度遍历,如果有A树中有某个节点与B根节点的值一致,就启动判断流程。
判断流程是A树从该节点开始,和B树一起深度遍历,所遍历到的节点,要么B树中不存在,要么B树节点的值和A树节点的值相同
遍历到B树节点为空,A树节点不为空,没关系的,也算是子结构
时间复杂度O(n * m),因为A树第一次遍历时间复杂度为O(n),如果调用判断流程,第二次AB树一起遍历时间复杂度为O(m)
空间复杂度为O(hA),最差情况为从A树根节点出发,遍历到A树叶节点
思路
代码
C++实现
时间复杂度:O(n*m)
空间复杂度:O(n)
有点类似对称树的思想。区别是这道题不一定是从根节点得到答案。
时间复杂度:O(n)
空间复杂度:A的高度
复杂度O(nm) O(n)
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
if(A null || B null){
return false;
}
}
假设树A的节点个数为 n, 树B为k,则
时间复杂度:isSubTree函数的时间复杂度为 O(k),所以时间复杂度为 O(n*k)。
空间复杂度:空间复杂度为树 A 的高度。