题目
题目来源
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
思路
1.第一个想法是考研时所学习的前序遍历和中序遍历可以唯一确定一棵树,可以根据这两个遍历来进行比较,最后发现了一个问题:此处的两个遍历可以确定是基于两个遍历是采用节点ABCD…等完成的,而不是给出具体的数据(由于数据相同会带来混淆),所以考虑不使用递归给出前序和中序之后再比较,而是在中序遍历过程中直接比较。(然而我写的代码真的又臭又长…空间和时间没一个能行的……)
2.采用递归的方式完成
相关思考
1.具体实现过程中,一开始只使用了一个while进行了比较,如果q有p没有的分支,就不能发现,所以在之前增加了q1、p1的循环。(如果分别入栈而不是通过这样的方式,还是会有一开始的问题,即中序遍历结果一样,但是实际上树形并不相同)
2.在看到评论中使用递归完成比较后进行了尝试,但是由于先比较p、q的val值所以产生报错,原因是p、q有可能为nullptr,一定要考虑了此种情况,确认二者均有val值后,再进行val的比较。
代码(C++/原创)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
stack<TreeNode*> s1,s2;
if(p==nullptr&&q==nullptr) return true;
else if(p==nullptr) return false;
else if(q==nullptr) return false;
auto p1=p,q1=q;
while(q1) //比较两个树的结构(这一部分不入栈)
{
if(p1==nullptr) return false;
p1=p1->left;
q1=q1->left;
}
while(p) //比较两个数的结构,入栈
{
if(q==nullptr) return false;
s1.push(p);
s2.push(q);
p=p->left;
q=q->left;
}
while(!s1.empty()&&!s2.empty())
{
auto node1 = s1.top();
auto node2 = s2.top();
s1.pop();
s2.pop();
if(node1->val!=node2->val) return false;//中序遍历过程中比较节点的数据
node1=node1->right;
node2=node2->right;
while(node1)
{
s1.push(node1);
node1=node1->left;
}
while(node2)
{
s2.push(node2);
node2=node2->left;
}
}
if(!(s1.empty()&&s2.empty())) return false; //若其中一个栈空了而另一个没空,说明两棵树的形状必然不相同
return true;
}
};
代码(C++/力扣)
bool isSameTree(struct TreeNode* p, struct TreeNode* q){
if(p==NULL&&q==NULL) return true;
if(p==NULL||q==NULL) return false;
if(p->val!=q->val) return false;
return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}