文章目录
Leetcode101
1.问题描述
2.解决方案
解法一:递归比较内侧外侧
class Solution3{
public:
bool compare(TreeNode* left,TreeNode* right){
if(left!= nullptr&&right== nullptr) return false;
if(left== nullptr&&right!= nullptr) return false;
if(left== nullptr&&right== nullptr) return true;
if(left!= nullptr&&right!= nullptr&&left->val!=right->val) return false;
//进入这说明是left!= nullptr&&right!= nullptr&&left->val==right->val的情况
bool outside= compare(left->left,right->right);
bool inside= compare(left->right,right->left);
return outside&&inside;
}
bool isSymmetric(TreeNode* root) {
if(root== nullptr) return true;
else return compare(root->left,root->right);
}
};
解法二:迭代法一对结点一对的比较
这个迭代法是使用队列类似于层序遍历,但是我一开始使用了两个队列分别存贮,这就导致了判断起来十分复杂,有多种特殊情况非常难实现,然后如果使用一个队列一次出队两个节点,这样就好判断了许多。
正确代码
class Solution2 {
public:
bool check(TreeNode* left, TreeNode* right) {
queue <TreeNode*> q;
q.push(left); q.push(right);
//选择一个队列进行比较而不是像上面的两个队列进行比较
while (!q.empty()) {
left = q.front(); q.pop();
right= q.front(); q.pop();
//比较的过程
//1.都空continue
if (!left && !right) continue;
//2.一个空一个不空 或者 两个不空但不相等 false
if ((!left || !right) || (left->val != right->val)) return false;
q.push(left->left);
q.push(right->right);
q.push(left->right);
q.push(right->left);
}
return true;
}
bool isSymmetric(TreeNode* root) {
if(root== nullptr) return true;
else return check(root->left,root->right);
}
};
错误代码
//迭代做法(错误)
class Solution {
public:
bool IsSamePoint(TreeNode* a,TreeNode* b){
if(a== nullptr&&b== nullptr) return true;
if(a!= nullptr&&b!= nullptr&&a->val==b->val) return true;
return false;
}
bool isSymmetric(TreeNode* root) {
if(root== nullptr) return true;
if(root!= nullptr&&root->left== nullptr&&root->right== nullptr) return true;
//q1层序入队顺序先左儿子后右儿子 q2入队顺序先右儿子后左儿子
queue<TreeNode*> q1;
queue<TreeNode*> q2;
q1.push(root);
q2.push(root);
while(q1.empty()== false&&q2.empty()== false){
TreeNode* t1=q1.front();
TreeNode* t2=q2.front();
q1.pop();
q2.pop();
if(IsSamePoint(t1,t2)== false) return false;
if(t1== nullptr&&t2== nullptr) continue;
if(t1->left== nullptr&&t1->right== nullptr) continue;
if(t2->left== nullptr&&t2->right== nullptr) continue;
q1.push(t1->left);
q1.push(t1->right);
q2.push(t2->right);
q2.push(t2->left);
}
return true;
}
};
Leetcode100
1.题目描述
2.解决方案
解法一:递归
和101的思路几乎一样的
//正确递归解法
class Solution1 {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
//先检查
if(p== nullptr&&q== nullptr) return true;
if(p!= nullptr&&q== nullptr) return false;
if(p== nullptr&&q!= nullptr) return false;
//当前结点相同以及左右子树相同
return (p->val==q->val)&&isSameTree(p->right,q->right)&&isSameTree(p->left,q->left);
}
};
解法二:迭代
迭代法就和101的迭代一样,就是使用队列或者栈,一对节点一对节点的进行比较,代码这里就不给出了
Leetcode572
1.问题描述
2.解决方案
思路呢,很简单就是前序遍历root树,对每一个结点都和subRoot进行判断是否为同一棵树,至于判断同一棵树的功能就是上一题100的,一模一样,所以问题就是前序遍历root树的细节
1.首先下次回来复习的时候我希望我能再认真分析一次这个递归过程,就是if(递归调用= =true) return true,这个逻辑是怎么传回原函数等等
2.这个遍历逻辑一开始大意了写成了if(isSame(root->left,subRoot) = = true) return true,当时是错的,这样相当于只判断了一次没有递归判断
3.后来又出现了一个问题那就是如果root= =nullpter,if(isSame(root,subRoot)== true) return true,那么如果在第一层判断中没有return true,那么自然就会进入后面的逻辑isSubtree(root->left,subRoot),那么问题来了root->left就段错误了,所以加了一个root!=nullptr,就AC了但是没分析的很清楚这个root和subRoot的空与不空的关系
class Solution {
public:
bool isSame(TreeNode* p,TreeNode* q){
//1.
if(p!= nullptr&&q== nullptr) return false;
if(p== nullptr&&q!= nullptr) return false;
if(p== nullptr&&q== nullptr) return true;
if(p!= nullptr&&q!= nullptr&&p->val!=q->val) return false;
//2.if(p!= nullptr&&q!= nullptr&&p->val==q->val)
return isSame(p->left,q->left)&& isSame(p->right,q->right);
}
bool isSubtree(TreeNode* root, TreeNode* subRoot) {
if(isSame(root,subRoot)== true) return true;
//if(isSame(root->left,subRoot)== true) return true;
//if(isSame(root->right,subRoot)== true) return true;
if(root!= nullptr&&isSubtree(root->left,subRoot)== true) return true;
if(root!= nullptr&&isSubtree(root->right,subRoot)== true) return true;
return false;
}
};