题目3: 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
- 两棵树上的节点数目都在范围
思路分析
方法一:同时前序遍历两颗树中的每一个节点,使用一个全局变量记录不相等节点的个数,此方法一直遍历完整棵树才会停。
两棵树判断相等的情况,有哪些?
当前节点为空:如果有一颗树当前节点为空,那么另一个也一定为空 p == q
当前节点不为空:不为空,则判断两个节点当前值是否相等 p->val == q->val
上面的这两步即为当前节点要做的事情,剩下的交给递归框架。
程序代码
// https://leetcode.cn/problems/same-tree/description/
// 100. 相同的树
#include<iostream>
using namespace std;
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 {
private:
// 定义全局变量,记录是否有不相等的节点
int res = 0;
public:
void travel(TreeNode* p, TreeNode* q)
{
if(p == NULL || q == NULL)
{
res += p == q ? 0 : 1;
return;
}
res += p->val == q->val ? 0 : 1;
travel(p->left,q->left);
travel(p->right,q->right);
}
bool isSameTree(TreeNode* p, TreeNode* q) {
travel(p,q);
return res == 0;
}
};
复杂度分析
时间复杂度: 把两棵树中小树遍历完成就可以判断,因此时间复杂度为O(min(m,n)),其中 m 和 n 分别是两个二叉树的节点数。
空间复杂度:空间复杂度取决于递归调用的层数,递归调用的层数不会超过较小的二叉树的最大高度,因此空间复杂度为O(min(m,n)) ,最坏情况下,二叉树的高度等于节点数。
思路分析
方法二:同时前序遍历两颗树中的每一个节点,遇到不相等节点就返回。代码非常简练,建议使用此方法。
程序代码
class Solution {
public:
bool travel(TreeNode* p, TreeNode* q)
{
if(p == NULL || q == NULL)
{
return p == q;
}
// 简练
return p->val == q->val && travel(p->left,q->left) && travel(p->right,q->right);
}
bool isSameTree(TreeNode* p, TreeNode* q) {
return travel(p,q);
}
};
复杂度分析
时间复杂度: 至多把两棵树中小树遍历完成就可以判断,因此时间复杂度为O(min(m,n)),其中 m 和 n 分别是两个二叉树的节点数。
空间复杂度:空间复杂度取决于递归调用的层数,递归调用的层数不会超过较小的二叉树的最大高度,因此空间复杂度为O(min(m,n)) ,最坏情况下,二叉树的高度等于节点数。
题目感悟
在函数中第一次遇到同时传参两棵树的情况,从代码的递归框架来看和传一棵树时,没有发生变化,所以从心理上不要惧怕。
更多相关知识:github.com/pingguo1987…