class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
// edge case
if (B == NULL || A == NULL) return false;
/// B 為 A 的子結構有三種情況,滿足任意一種即可:
// 1. B 的子結構起點為 A 的根節點,此時結果為 isTheSame(A, B)
// 2. B 的子結構起點隱藏在 A 的左子樹中,而不是直接為 A 的根節點,此時結果為 isSubStructure(A->left, B)
// 3. B 的子結構起點隱藏在 A 的右子樹中,此時結果為 isSubStructure(A->right, B)
return isTheSame(A, B) || isSubStructure(A->left, B) || isSubStructure(A->right, B);
}
bool isTheSame(TreeNode* root, TreeNode* subroot) {
if ( subroot == NULL) return true;
if (root == NULL || subroot == NULL) return false;
if (root == NULL || root->val != subroot->val) {
return false;
}
// 當 A 與 B 當前節點值相等時,若要判斷 B 為 A 的子結構
// 還需要判斷 B 的左子樹是否為 A 左子樹的子結構,以及 B 的右子樹是否為 A 右子樹的子結構
// 若兩者都滿足,就說明 B 是 A 的子結構,且該子結構以 A 根節點為起點
return isTheSame(root->left, subroot->left) && isTheSame(root->right, subroot->right);
}
};
class Solution:
# def isroot(self, A: TreeNode, B: TreeNode) -> TreeNode:
# if not B:
# return None
# root = B
# if not A.left:
# if A.val != B.val:
# root = self.isroot(A.left,B)
# if not A.right:
# if A.val != B.val:
# root = self.isroot(A.right,B)
# return root
def issame(self, A: TreeNode, B: TreeNode) -> bool:
if not B:
return True
if not A or A.val != B.val:
return False
return self.issame(A.left, B.left) and self.issame(A.right, B.right)
def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
return bool(A and B) and (self.issame(A,B) or self.isSubStructure(A.left,B) or self.isSubStructure(A.right,B))
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
if (A == null || B == null) {
return false;
}
if (A.val == B.val) {
boolean l = true, r = true;
if (B.left != null){
l = isContinued(A.left, B.left);
}
if (B.right != null) {
r = isContinued(A.right, B.right);
}
if (l && r) {
return true;
}
}
return isSubStructure(A.left, B) || isSubStructure(A.right, B);
}
public boolean isContinued(TreeNode A, TreeNode B) {
if (A == null || B == null || A.val != B.val) {
return false;
}
if (B.left != null) {
boolean flag = isContinued(A.left, B.left);
if (flag == false) {
return false;
}
}
if (B.right != null) {
boolean flag = isContinued(A.right, B.right);
if (flag == false) {
return false;
}
}
return true;
}
}
共以下 20 个回答
bool isSubStructure(TreeNode* A, TreeNode* B) //判断是否子树结构
{
if (!B) return true;
if (!A || !B->left || !B->right) return false;
return isSame(A, B->left) && isSubStructure(A, B->right);
}
bool isSame(TreeNode* A, TreeNode* B) //判断是否同一结构
{
if (!A && !B) return true;
if (!A || !B) return false;
return A->val B->val && isSame(A->left, B->left) && isSame(A->right, B->right);
}//时间复杂度O(n),空间复杂度O(n)
//A 节点为N B节点为M
//时间复杂度为O(NM)
//空间复杂度为O(M)
class Solution{
public:
bool 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;
}
bool isSubTree(TreeNode *Ta,TreeNode *Tb)
{
if(Tb NULL)//子节点为空
return true;
if(Ta NULL)//原节点为空
return false;
if(Ta->val!= Tb->val)//只要有一个节点不为NULL
return false;
return isSubTree(Ta->left,Tb->left)&&(isSubTree(Ta->right,Tb->right));//遍历到下一个节点
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
// 判断当A和B得根节点相同时,B和A后面的节点相同吗
bool issubTree(TreeNode A, TreeNode *B){
if (!B) return true; // 递归结束条件1,A的一个节点,B的对应位置没有,可以认为是子树
if (!A || A->val != B->val) // 递归结束条件2,B的一个节点,A的对应位置没有或者A,B对应位置节点值不同,返回false
return false;
return issubTree(A->left, B->left) && issubTree(A->right, B->right); // 继续在对应位置递归
}
};
打卡
A的节点数N,B的节点数M
时间复杂度:O(NM)
空间复杂度:O(M)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSubStructure(TreeNode A, TreeNode* B) {
if(BNULL) return false;
if(ANULL) return false;
if(A->valB->val&&isin(A,B)) return true;
else return isSubStructure(A->left,B)||isSubStructure(A->right,B);
}
bool isin(TreeNode* A,TreeNode* B){
if(BNULL) return true;
if(ANULL) return false;
if(A->valB->val)
return isin(A->left,B->left)&&isin(A->right,B->right);
else return false;
}
};
時間複雜度 : O(MN) 空間複雜度 : O(M) 最差情況為遍歷所有 A的節點 即為 M 個
java版
////俩函数,找到与子支相同的root,代入isame比较,对左右支进行递归对比,返回ture就是子支,
bool isSameNode(struct TreeNode* A, struct TreeNode*B){
if(B NULL)
return true;
else if(ANULL)
return false;
else if(A->val B->val)
return(isSameNode(A->left,B->left) && isSameNode(A->right,B->right));
return false;
}
bool isSubStructure(struct TreeNode* A, struct TreeNode* B){
if(BNULL || ANULL)
return false;
if(A->val B->val){
if(isSameNode(A,B))
return true;
else
return(isSubStructure(A->left,B) || isSubStructure(A->right,B));
}
else{
return(isSubStructure(A->left,B) || isSubStructure(A->right,B));
}
return true;
}
写的时候思路没问题, 但没有搞清楚如何把A的遍历和找子结构的函数结合起来,一开始的想法是,先写一个递归函数将A中与B的root节点相同的节点找到,然后再写一个递归函数去递归比较二者的子结构,实际上本身题目给的比较是否是子结构的函数,就可以实现递归遍历A节点,每次A的节点变动一下,以它为根的A的结构就去和B比较(也就是调用另一个函数),那么返回true的情况就是要么以A为根的满足或者是A.left为根满足或者是A.right为根满足。
class Solution:
# def isroot(self, A: TreeNode, B: TreeNode) -> TreeNode:
# if not B:
# return None
# root = B
# if not A.left:
# if A.val != B.val:
# root = self.isroot(A.left,B)
# if not A.right:
# if A.val != B.val:
# root = self.isroot(A.right,B)
空间复杂度O(n)时间复杂度O(n)
让a的每个点都去尝试与B匹配
打卡
1、树一般都用递归解决
时间复杂度O(n), 空间复杂度O(n)