class Solution {
// 判断 B 是否是 A 的子结构
// B 树要在结构上、数值上与 A 树的一部分完全一致才行
// 对 A 左子遍历的同时对 B 左子进行遍历
public boolean isSubStructure(TreeNode A, TreeNode B) {
if (A == null || B == null) {
return false;
}
if (isSubTree(A, B)) {
return true;
}
return isSubStructure(A.left, B) || isSubStructure(A.right, B);
}
private 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);
}
// 时间复杂度为 O(m * n)
// 两棵树都要被遍历
// 空间复杂度为 O(n)
// 对 A 树的所有节点都要进行遍历
}
/**
* 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) {
return (A != null && B != null) && (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;
}
return recur(A.left, B.left) && recur(A.right, B.right);
}
}
public boolean isSubStructure(TreeNode A, TreeNode B) {
if(Anull || Bnull) 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(Anull || A.val!=B.val) return false;
return recur(A.left, B.left)&&recur(A.right, B.right);
}
思路:
recur(A, B) 函数:
终止条件:
当节点 B 为空:说明树 B 已匹配完成(越过叶子节点),因此返回 true ;
当节点 A 为空:说明已经越过树 A 的叶节点,即匹配失败,返回 false;
当节点 A 和 B 的值不同:说明匹配失败,返回 false ;
返回值:
判断 A 和 B 的 左子节点 是否相等,即 recur(A.left, B.left) ;
判断 A 和 B 的 右子节点 是否相等,即 recur(A.right, B.right) ;
isSubStructure(A, B) 函数:
特例处理: 当 树 A 为空 或 树 B 为空 时,直接返回 false\text{false}false ;
返回值: 若树 B 是树 A 的子结构,则必满足以下三种情况之一,因此用或 || 连接;
以 节点 A 为根节点的子树 包含树 B ,对应 recur(A, B);
树 B 是 树 A 左子树 的子结构,对应 isSubStructure(A.left, B);
树 B 是 树 A 右子树 的子结构,对应 isSubStructure(A.right, B);
class Solution:
def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
def equalTree(A,B):
if not B:
return True
if not A or A.val != B.val:
return False
return equalTree(A.right,B.right) and equalTree(A.left,B.left)
if not A or not B:
return False
return equalTree(A,B) or self.isSubStructure(A.left,B) or self.isSubStructure(A.right,B)
“`C++
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
return (A != nullptr && B != nullptr) && (tree(A, B) || isSubStructure(A->left, B) || isSubStructure(A->right, B));
}
“`c++
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
if (A == nullptr || B == nullptr) return false;
if (isSame(A, B)) return true;
return isSubStructure(A->left, B) || isSubStructure(A->right, B);
}
bool isSame(TreeNode* A, TreeNode* B) {
if (B == nullptr) return true;
if (A == nullptr || A->val != B->val) return false;
return isSame(A->left, B->left) && isSame(A->right, B->right);
}
};
“`
共以下 27 个回答
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);
}
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 recur(A.left, B.left) && recur(A.right, B.right);
}
}时间复杂度O(MN)空间复杂度O(M)
day7第三题
时空复杂度O(n)
时间复杂度:isSubTree函数的时间复杂度为 O(k),所以时间复杂度为 O(n*k)。
空间复杂度:空间复杂度为树 A 的高度。
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
if(A NULL || B NULL) return false;
};
打卡
java
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
return (A != null && B != null) && (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;
return recur(A.left, B.left) && recur(A.right, B.right);
}
}
提交
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
if(Anull||Bnull)
return false;
if(isSame(A,B))
return true;
return isSubStructure(A.left,B)||isSubStructure(A.right,B);
}
public boolean isSame(TreeNode A,TreeNode B)
{
if(Anull&&Bnull)
return true;
if(A!=null&&Bnull)
return true;
if(Anull&&B!=null)
return false;
if(A.val!=B.val)
return false;
return isSame(A.left,B.left)&&isSame(A.right,B.right);
}
}
遍历所有节点,然后对应去查子结构和当前节点的结构是否相同
时间复杂度$O(MN)$,空间复杂度O(logM*logN) 跟树的深度有关
时间复杂度:
O(M * N) 分别要遍历两棵树
空间复杂度:
O(logM * logN) 跟树的深度有关,递归执行会使用函数执行栈暂存
假设树A的节点个数为 n, 树B为k,则
时间复杂度:isSubTree函数的时间复杂度为 O(k),所以时间复杂度为 O(n*k)。
空间复杂度:空间复杂度为树 A 的高度。
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
if(A null || B null)return false; // 空树 不会是以 tree1 的某个节点为根的子树具有 相同的结构和节点值
return check(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B);
}
public boolean check(TreeNode a, TreeNode b){
if(b null)return true;// 终止条件
if(a null || a.val != b.val)return false;
return check(a.left, b.left) && check(a.right, b.right);
}
}
子结构,考虑一些边界情况
public boolean isSubStructure(TreeNode A, TreeNode B) {
if(Anull || Bnull) 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(Anull || A.val!=B.val) return false;
return recur(A.left, B.left)&&recur(A.right, B.right);
思路:
recur(A, B) 函数:
终止条件:
当节点 B 为空:说明树 B 已匹配完成(越过叶子节点),因此返回 true ;
当节点 A 为空:说明已经越过树 A 的叶节点,即匹配失败,返回 false;
当节点 A 和 B 的值不同:说明匹配失败,返回 false ;
返回值:
判断 A 和 B 的 左子节点 是否相等,即 recur(A.left, B.left) ;
判断 A 和 B 的 右子节点 是否相等,即 recur(A.right, B.right) ;
isSubStructure(A, B) 函数:
特例处理: 当 树 A 为空 或 树 B 为空 时,直接返回 false\text{false}false ;
返回值: 若树 B 是树 A 的子结构,则必满足以下三种情况之一,因此用或 || 连接;
以 节点 A 为根节点的子树 包含树 B ,对应 recur(A, B);
树 B 是 树 A 左子树 的子结构,对应 isSubStructure(A.left, B);
树 B 是 树 A 右子树 的子结构,对应 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:
def equalTree(A,B):
if not B:
return True
if not A or A.val != B.val:
return False
return equalTree(A.right,B.right) and equalTree(A.left,B.left)
时间O(MN)
O(N)
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
if(A nullptr || B nullptr) return false;
if(judge(A, B)) return true;
return isSubStructure(A->left, B) || isSubStructure(A->right, B);
}
bool judge(TreeNode* A, TreeNode* B){
if(B nullptr) return true;
if(A nullptr || A->val != B->val) return false;
return judge(A->left, B->left) && judge(A->right, B->right);
}
};
//先序遍历+判断是否为子树。
时间复杂度O(n^2)
空间复杂度O(2n)
“`C++
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
return (A != nullptr && B != nullptr) && (tree(A, B) || isSubStructure(A->left, B) || isSubStructure(A->right, B));
}
};
“`
思路:递归判断A的每一个节点与B是否可能是相同的结构。
“`c++
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
if (A == nullptr || B == nullptr) return false;
if (isSame(A, B)) return true;
return isSubStructure(A->left, B) || isSubStructure(A->right, B);
}
bool isSame(TreeNode* A, TreeNode* B) {
if (B == nullptr) return true;
if (A == nullptr || A->val != B->val) return false;
return isSame(A->left, B->left) && isSame(A->right, B->right);
}
};
“`
假设树A的节点个数为 n, 树B为k,则
时间复杂度:isSubTree函数的时间复杂度为 O(k),所以时间复杂度为 O(n*k)。
空间复杂度:空间复杂度为树 A 的高度。
class Solution {
public boolean isSub(TreeNode A,TreeNode B){
if(B null)
return true;
return A!=null && A.valB.val &&isSub(A.left,B.left) && isSub(A.right,B.right);
}
}
//递归先找到父节值相等的两个点,再递归判断其子节点是否相同。
//
//A有m个节点,B有n个,时间复杂度O(mn) 空间复杂度Om