剑指Offer26 -- 树
1. 题目描述
剑指 Offer 26. 树的子结
2. 思路
1.暴力,枚举 A A A 中的每个节点,对于该节点 d f s dfs dfs 查找 B B B,时间复杂度为 O ( N 2 ) O(N^2) O(N2), N N N 为节点数。经典的 d f s dfs dfs 套 d f s dfs dfs,爆搜出奇迹!当然,爆搜归爆搜,不要忘了剪枝。小小的剪枝大大的优化。
2.好像没有优化的做法?
3. 代码-暴力
有个小优化,那就是在枚举每个点,并以当前点搜索的时候,要保证
a
a
a 和
b
b
b 的
v
a
l
val
val 相等,否则就不搜,这样可以节省很多时间。
另外,将是否找到作为一个全局标记
h
a
s
r
e
s
has_res
hasres,当已经找到后,后面的就不着了,提前结束
d
f
s
dfs
dfs。
/**
* 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 {
private:
bool has_res;
bool dfs_check(TreeNode *a, TreeNode *b) {
// 如果 b 为空,无论 a 是否为空,都说明此时 b 是 a 的一部分
if(b == nullptr) return true;
// b 不为空,a 为空,那么 b 无论如何都不可能是 a 的一部分
if(a == nullptr) return false;
if(a->val != b->val) return false;
if(!dfs_check(a->left, b->left)) return false;
if(!dfs_check(a->right, b->right)) return false;
return true;
}
// b must not nullptr
void dfs_split(TreeNode* a, TreeNode *b) {
if(a == nullptr) return ;
if(has_res) return ;
if(a->val == b->val && dfs_check(a, b)) { // 小优化
has_res = true;
return ;
}
dfs_split(a->left, b);
dfs_split(a->right, b);
}
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
if(B == nullptr || A == nullptr) return false;
has_res = false;
dfs_split(A, B);
return has_res;
}
};