Given two binary trees, write a function to check if they are the same or not.

Two binary trees are considered the same if they are structurally identical and the nodes have the same value.

Example 1:

  1. Input: 1 1
  2. / \ / \
  3. 2 3 2 3
  4.  
  5. [1,2,3], [1,2,3]
  6.  
  7. Output: true

Example 2:

  1. Input: 1 1
  2. / \
  3. 2 2
  4.  
  5. [1,2], [1,null,2]
  6.  
  7. Output: false

Example 3:

  1. Input: 1 1
  2. / \ / \
  3. 2 1 1 2
  4.  
  5. [1,2,1], [1,1,2]
  6.  
  7. Output: false

判断两棵树是否相同和之前的判断两棵树是否对称都是一样的原理,利用深度优先搜索 DFS 来递归。代码如下:

解法一:

  1. class Solution {
  2. public:
  3. bool isSameTree(TreeNode *p, TreeNode *q) {
  4. if (!p && !q) return true;
  5. if ((p && !q) || (!p && q) || (p->val != q->val)) return false;
  6. return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
  7. }
  8. };

这道题还有非递归的解法,因为二叉树的四种遍历(层序,先序,中序,后序)均有各自的迭代和递归的写法,这里我们先来看先序的迭代写法,相当于同时遍历两个数,然后每个节点都进行比较,可参见之间那道 Binary Tree Preorder Traversal,参见代码如下:

解法二:

  1. class Solution {
  2. public:
  3. bool isSameTree(TreeNode* p, TreeNode* q) {
  4. stack<TreeNode*> st;
  5. st.push(p); st.push(q);
  6. while (!st.empty()) {
  7. p = st.top(); st.pop();
  8. q = st.top(); st.pop();
  9. if (!p && !q) continue;
  10. if ((p && !q) || (!p && q) || (p->val != q->val)) return false;
  11. st.push(p->right); st.push(q->right);
  12. st.push(p->left); st.push(q->left);
  13. }
  14. return true;
  15. }
  16. };

也可以使用中序遍历的迭代写法,对应之前那道 Binary Tree Inorder Traversal,参见代码如下:

解法三:

  1. class Solution {
  2. public:
  3. bool isSameTree(TreeNode* p, TreeNode* q) {
  4. stack<TreeNode*> st;
  5. while (p || q || !st.empty()) {
  6. while (p || q) {
  7. if ((p && !q) || (!p && q) || (p->val != q->val)) return false;
  8. st.push(p); st.push(q);
  9. p = p->left; q = q->left;
  10. }
  11. p = st.top(); st.pop();
  12. q = st.top(); st.pop();
  13. p = p->right; q = q->right;
  14. }
  15. return true;
  16. }
  17. };

对于后序遍历的迭代写法,貌似无法只是用一个栈来做,因为每次取出栈顶元素后不立马移除,这样使用一个栈的话两棵树结点的位置关系就会错乱,分别使用各自的栈就好了,对应之前那道 Binary Tree Postorder Traversal,参见代码如下:

解法四:

  1. class Solution {
  2. public:
  3. bool isSameTree(TreeNode* p, TreeNode* q) {
  4. stack<TreeNode*> st1, st2;
  5. TreeNode *head1, *head2;
  6. while (p || q || !st1.empty() || !st2.empty()) {
  7. while (p || q) {
  8. if ((p && !q) || (!p && q) || (p->val != q->val)) return false;
  9. st1.push(p); st2.push(q);
  10. p = p->left; q = q->left;
  11. }
  12. p = st1.top();
  13. q = st2.top();
  14. if ((!p->right || p->right == head1) && (!q->right || q->right == head2)) {
  15. st1.pop(); st2.pop();
  16. head1 = p; head2 = q;
  17. p = nullptr; q = nullptr;
  18. } else {
  19. p = p->right;
  20. q = q->right;
  21. }
  22. }
  23. return true;
  24. }
  25. };

对于层序遍历的迭代写法,其实跟先序遍历的迭代写法非常的类似,只不过把栈换成了队列,对应之前那道 Binary Tree Level Order Traversal,参见代码如下:

解法五:

  1. class Solution {
  2. public:
  3. bool isSameTree(TreeNode* p, TreeNode* q) {
  4. queue<TreeNode*> que;
  5. que.push(p); que.push(q);
  6. while (!que.empty()) {
  7. p = que.front(); que.pop();
  8. q = que.front(); que.pop();
  9. if (!p && !q) continue;
  10. if ((p && !q) || (!p && q) || (p->val != q->val)) return false;
  11. que.push(p->right); que.push(q->right);
  12. que.push(p->left); que.push(q->left);
  13. }
  14. return true;
  15. }
  16. };

Github 同步地址:

https://github.com/grandyang/leetcode/issues/100

类似题目:

Binary Tree Preorder Traversal

Binary Tree Inorder Traversal

Binary Tree Postorder Traversal

Binary Tree Level Order Traversal

参考资料:

https://leetcode.com/problems/same-tree/

https://leetcode.com/problems/same-tree/discuss/32684/My-non-recursive-method

https://leetcode.com/problems/same-tree/discuss/32687/Five-line-Java-solution-with-recursion

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Same Tree 判断相同树的更多相关文章

  1. [LeetCode] Symmetric Tree 判断对称树

    Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). For e ...

  2. [Leetcode] Same tree判断是否为相同树

    Given two binary trees, write a function to check if they are equal or not. Two binary trees are con ...

  3. LeetCode 101. Symmetric Tree 判断对称树 C++

    Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). For e ...

  4. 二叉树系列 - [LeetCode] Symmetric Tree 判断二叉树是否对称,递归和非递归实现

    Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). For e ...

  5. LeetCode Same Tree (判断相同树)

    题意:如题 思路:递归解决,同判断对称树的原理差不多.先保证当前两个结点是相等的,再递归保证两左结点是相等的,再递归保证右结点是相等的. /** * Definition for a binary t ...

  6. 【LeetCode】572. 另一个树的子树 Subtree of Another Tree(Python & Java)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:先序遍历 方法二:DFS + DFS 方法三 ...

  7. EasyUI Tree判断节点是否是叶

    方法1:  $('#domaincatalog').tree('isLeaf', node.target); 返回true或false ,true表示是叶节点, false即不是 方法2:官方文档中: ...

  8. LeetCode: Binary Tree Traversal

    LeetCode: Binary Tree Traversal 题目:树的先序和后序. 后序地址:https://oj.leetcode.com/problems/binary-tree-postor ...

  9. 【IT笔试面试题整理】判断一个树是否是另一个的子树

    [试题描述]定义一个函数,输入判断一个树是否是另一个对的子树 You have two very large binary trees: T1, with millions of nodes, and ...

随机推荐

  1. javaWeb应用打包

    在Java中,使用"jar"命令来对将JavaWeb应用打包成一个War包,jar命令的用法如下:

  2. WebComponent魔法堂:深究Custom Element 之 标准构建

    前言  通过<WebComponent魔法堂:深究Custom Element 之 面向痛点编程>,我们明白到其实Custom Element并不是什么新东西,我们甚至可以在IE5.5上定 ...

  3. CentOS系统MySQL双机热备配置

    1  概述 在集成项目中需要应对不同环境下的安装配置,主流操作系统大致可以分为三种:Linux.Windows以及UNIX.其中Linux备受青睐的主要原因有两个: 首先,Linux作为自由软件有两个 ...

  4. java JSP(原创新手可进)

    一. 同等编程方式jsp与asp.net的不同 app需要做一个简单网站,和几个用户推广链接,所以涉及到web这块开发,原本昨天想直接使用asp.net来做,但是之后放弃了这个想法,因为数据访问接口都 ...

  5. 手游聚合SDK开发之远程开关---渠道登入白名单

    白名单有啥好说的呢?无非就是筛选登入,大家第一眼看到就是这个印象,白名单也是有文章的,弄的时机不同会给你带来很不错的收益,注意是收益.还是举例来说,游戏上线前渠道都会做一个预下载,一般提前1-2天,这 ...

  6. java类与实例

    最近在看设计模式,感觉自己对java的三大特性的理解不够清晰,搞不清楚抽象类.接口.泛型的用处和优缺点.设计模式学了一半,想着还是停下来脑补一下java的基础,就从java对象开始吧. 一.java对 ...

  7. Canvas设置width与height 的问题!

    最近因为工作需要,所以就学了一下Html中的Canvas标签. 当我看了一下教程后,自己写了一个hello world的时候,麻烦事就出现了.看下面代码: <!DOCTYPE html> ...

  8. 如何利用BI实现人力资源可视化管理

    随着通信行业改革的不断深化,行业的发展形势和生存环境正发生巨大变化,通信和信息的边界越来越模糊,市场竞争也随之愈演愈烈.近年来,某通讯运营商在业务的转型.网络的转型取得了巨大的突破,但人力资源管理的转 ...

  9. android 自定义控件——(五)按钮点击变色

    ----------------------------------按钮点击变色(源代码下有属性解释)------------------------------------------------- ...

  10. fastjson 混淆注意事项

    使用fastjson 注意事项,主要表现: 1.加了符号Annotation 的实体类,一使用就会奔溃 2.当有泛型属性时,一使用就奔溃 在调试的时候不会报错,当你要打包签名混淆包的时候,就会出现上述 ...