题目链接:100. 相同的树
题目:
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:
输入:p = [1,2,3], q = [1,2,3]
输出:true
示例 2:
输入:p = [1,2], q = [1,null,2]
输出:false
示例 3:
输入:p = [1,2,1], q = [1,1,2]
输出:false
提示:
- 两棵树上的节点数目都在范围 [0, 100] 内
- -104 <= Node.val <= 104
方案一:递归
用递归法之前可以先提前了解“递归三部曲”。
本题的三部曲是:
1、确定递归的参数和返回值:比较两树是否相同需要一 一比较参数两树对应的节点是否相同,则递归的参数是两个树的节点,返回值是布尔类型,那么可以直接用题目给的函数isSameTree()。
bool isSameTree(TreeNode* p, TreeNode* q) {}
2、确定终止条件:在两树的节点比较中,如果都为空,则节点相同;如果任意一个为空或节点值不同,则节点不相同。剩下的就是节点值相等的情况。
//如果两树的节点都为空,则节点相同
if (!p && !q) return true;
//如果两树的节点任意一个为空,则节点不相同
else if (!p || !q) return false;
//如果两树的节点值不同,则节点不相同
else if (p->val != q->val) return false;
3、确定单层逻辑:递归两树的左子树和右子树,左子树和右子树都相同,则return true,反之return false。
return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
代码(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) {
//确定终止条件
//如果两树的节点都为空,则节点相同
if (!p && !q) return true;
//如果两树的节点任意一个为空,则节点不相同
else if (!p || !q) return false;
//如果两树的节点值不同,则节点不相同
else if (p->val != q->val) return false;
//确定单层逻辑
//递归两树的左子树和右子树
//左子树和右子树都相同,则为true,反之为false
else return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
};
方案二:迭代
1、用队列来比较两树是否相同
//迭代
//用队列实现
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
queue<TreeNode*> que;
que.push(p); //将第一棵树的根节点放入队列
que.push(q); //将第二棵树的根节点放入队列
while (!que.empty()) {
TreeNode* firstTreeNode = que.front(); //取出第一棵树的根节点
que.pop();
TreeNode* secondTreeNode = que.front(); //取出第二棵树的根节点
que.pop();
//两树的节点都为空,则节点相同-->结束本次循环
if (!firstTreeNode && !secondTreeNode) continue;
//两树对应的节点任意一个为空或节点值不等,则节点不同
else if (!firstTreeNode || !secondTreeNode || firstTreeNode->val != secondTreeNode->val) return false;
//将两树节点的左右孩子分别放入队列
que.push(firstTreeNode->left);
que.push(secondTreeNode->left);
que.push(firstTreeNode->right);
que.push(secondTreeNode->right);
}
return true;
}
};
2、用栈来比较两树是否相同
不管用什么容器解决,目的都是一样的。
//迭代
//用栈实现
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
stack<TreeNode*> stk;
stk.push(p); //将第一棵树的根节点压栈
stk.push(q); //将第二棵树的根节点压栈
while (!stk.empty()) {
TreeNode* secondTreeNode = stk.top(); //取出第二棵树的根节点
stk.pop();
TreeNode* firstTreeNode = stk.top(); //取出第一棵树的根节点
stk.pop();
//两树的节点都为空,则节点相同-->结束本次循环
if (!firstTreeNode && !secondTreeNode) continue;
//两树对应的节点任意一个为空或节点值不等,则节点不同
else if (!firstTreeNode || !secondTreeNode || firstTreeNode->val != secondTreeNode->val) return false;
//将两树节点的左右孩子分别压栈
stk.push(firstTreeNode->left);
stk.push(secondTreeNode->left);
stk.push(firstTreeNode->right);
stk.push(secondTreeNode->right);
}
return true;
}
};