PROBLEM
剑指 Offer 26. 树的子结构
难度 中等
MY ANSWER
使用bfs遍历A,找到与B头节点值相等的节点,调用judge,分别使用bfs遍历进行比较。若有一次judge调用返回true,则说明A包含B。M为A节点数,N为B节点数,时间复杂度O(MN),空间复杂度O(M)。
class Solution { public: bool judge(TreeNode* A, TreeNode* B) { queue<TreeNode*> m; queue<TreeNode*> n; m.push(A); n.push(B); while(1) { TreeNode* anode = m.front(); TreeNode* bnode = n.front(); if(!anode && bnode) { return false; } if(anode && !bnode) { m.pop(); n.pop(); if(n.empty()) { break; } continue; } if(!anode && !bnode) { m.pop(); n.pop(); if(n.empty()) { break; } continue; } if(anode->val != bnode->val) { return false; } else { m.pop(); m.push(anode->left); m.push(anode->right); n.pop(); n.push(bnode->left); n.push(bnode->right); } if(m.empty()) { break; } } return true; }
bool isSubStructure(TreeNode* A, TreeNode* B) { int flag = 0; queue<TreeNode*> tmp; tmp.push(A); if(!B || !A) { return false; } while(!tmp.empty()) { TreeNode* node = tmp.front(); if(node == NULL) { tmp.pop(); } else if(node->val == B->val) { flag += judge(node, B); tmp.pop(); tmp.push(node->left); tmp.push(node->right); } else { tmp.pop(); tmp.push(node->left); tmp.push(node->right); } } return flag; } };
|
BETTER SOLUTION
使用两个递归,首先调用isSubStructure前序遍历树A的节点,然后调用judge判断以结点为根节点的子树是否包含树B。M为A节点数,N为B节点数,时间复杂度O(MN),空间复杂度O(M)。
class Solution { public: bool judge(TreeNode* a, TreeNode* b) { if(!b) { return true; } if(!a || a->val != b->val) { return false; } return judge(a->left, b->left) && judge(a->right, b->right); } bool isSubStructure(TreeNode* A, TreeNode* B) { if(!B || !A) { return false; } return judge(A, B) || isSubStructure(A->left, B) || isSubStructure(A->right, B); } };
|
SUMMARY
树的相关问题考虑递归,设计递归时关注函数的功能、中止条件、返回值,不需要过于纠结运行细节。