C++实现LeetCode(100.判断相同树)

[LeetCode] 100. Same Tree 判断相同树

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:

Input:     1         1
    / \       / \
2   3     2   3

        [1,2,3],   [1,2,3]

Output: true

Example 2:

Input:     1         1
/           \
2             2

[1,2],     [1,null,2]

Output: false

Example 3:

Input:     1         1
/ \       / \
2   1     1   2

[1,2,1],   [1,1,2]

Output: false

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

解法一:

class Solution {
public:
    bool isSameTree(TreeNode *p, TreeNode *q) {
        if (!p && !q) return true;
        if ((p && !q) || (!p && q) || (p->val != q->val)) return false;
        return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
    }
};

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

解法二:

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        stack<TreeNode*> st;
        st.push(p); st.push(q);
        while (!st.empty()) {
            p = st.top(); st.pop();
            q = st.top(); st.pop();
            if (!p && !q) continue;
            if ((p && !q) || (!p && q) || (p->val != q->val)) return false;
            st.push(p->right); st.push(q->right);
            st.push(p->left); st.push(q->left);
        }
        return true;
    }
};

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

解法三:

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        stack<TreeNode*> st;
        while (p || q || !st.empty()) {
            while (p || q) {
                if ((p && !q) || (!p && q) || (p->val != q->val)) return false;
                st.push(p); st.push(q);
                p = p->left; q = q->left;
            }
            p = st.top(); st.pop();
            q = st.top(); st.pop();
            p = p->right; q = q->right;
        }
        return true;
    }
};

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

解法四:

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        stack<TreeNode*> st1, st2;
        TreeNode *head1, *head2;
        while (p || q || !st1.empty() || !st2.empty()) {
            while (p || q) {
                if ((p && !q) || (!p && q) || (p->val != q->val)) return false;
                st1.push(p); st2.push(q);
                p = p->left; q = q->left;
            }
            p = st1.top();
            q = st2.top();
            if ((!p->right || p->right == head1) && (!q->right || q->right == head2)) {
                st1.pop(); st2.pop();
                head1 = p; head2 = q;
                p = nullptr; q = nullptr;
            } else {
                p = p->right;
                q = q->right;
            }
        }
        return true;
    }
};

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

解法五:

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        queue<TreeNode*> que;
        que.push(p); que.push(q);
        while (!que.empty()) {
            p = que.front(); que.pop();
            q = que.front(); que.pop();
            if (!p && !q) continue;
            if ((p && !q) || (!p && q) || (p->val != q->val)) return false;
            que.push(p->right); que.push(q->right);
            que.push(p->left); que.push(q->left);
        }
        return true;
    }
};

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

到此这篇关于C++实现LeetCode(100.判断相同树)的文章就介绍到这了,更多相关C++实现判断相同树内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2021-07-19

C++实现LeetCode(99.复原二叉搜索树)

[LeetCode] 99. Recover Binary Search Tree 复原二叉搜索树 Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure. Example 1: Input: [1,3,null,null,2]    1 / 3 \ 2 Output: [3,1,null,null,2]    3 / 1

C++实现LeetCode(139.拆分词句)

[LeetCode] 139. Word Break 拆分词句 Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words. Note: The same word in the dic

C++实现LeetCode(145.二叉树的后序遍历)

[LeetCode] 145. Binary Tree Postorder Traversal 二叉树的后序遍历 Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary tree {1,#,2,3},    1 \ 2 / 3 return [3,2,1]. Note: Recursive solution is trivial, could you d

C++实现LeetCode(102.二叉树层序遍历)

[LeetCode] 102. Binary Tree Level Order Traversal 二叉树层序遍历 Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). For example: Given binary tree {3,9,20,#,#,15,7},     3 / \ 9  20 /  \ 15 

C++实现LeetCode(312.打气球游戏)

[LeetCode] 312. Burst Balloons 打气球游戏 Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by array nums. You are asked to burst all the balloons. If the you burst balloon iyou will get nums[left] * nums[i]

C++实现LeetCode(107.二叉树层序遍历之二)

[LeetCode] 107. Binary Tree Level Order Traversal II 二叉树层序遍历之二 Given the root of a binary tree, return the bottom-up level order traversal of its nodes' values. (i.e., from left to right, level by level from leaf to root). Example 1: Input: root = [3

C++实现LeetCode(97.交织相错的字符串)

[LeetCode] 97.Interleaving String 交织相错的字符串 Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. Example 1: Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac" Output: true Example 2: Input: s1 = &quo

C++实现LeetCode(103.二叉树的之字形层序遍历)

[LeetCode] 103. Binary Tree Zigzag Level Order Traversal 二叉树的之字形层序遍历 Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). For example

C++实现LeetCode(98.验证二叉搜索树)

[LeetCode] 98. Validate Binary Search Tree 验证二叉搜索树 Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as follows: The left subtree of a node contains only nodes with keys less than the node's key. The ri

Javascript实现从小到大的数组转换成二叉搜索树

废话不多说了,直接给大家贴代码了,具体代码如下所示: var Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; var Tree = createTree(Array); console.log(Tree); // 构造一个节点 function Node(nodeData, leftData, rightData) { this.nodeData = nodeData; this.leftData = leftData; this.rightData = rig

Python二叉搜索树与双向链表转换实现方法

本文实例讲述了Python二叉搜索树与双向链表实现方法.分享给大家供大家参考,具体如下: # encoding=utf8 ''' 题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表. 要求不能创建任何新的结点,只能调整树中结点指针的指向. ''' class BinaryTreeNode(): def __init__(self, value, left = None, right = None): self.value = value self.left = left self.

javascript算法之二叉搜索树的示例代码

什么是二叉树 二叉树就是树的每个节点最多只能有两个子节点 什么是二叉搜索树 二叉搜索树在二叉树的基础上,多了一个条件,就是二叉树在插入值时,若插入值比当前节点小,就插入到左节点,否则插入到右节点:若插入过程中,左节点或右节点已经存在,那么继续按如上规则比较,直到遇到一个新的节点. 二叉搜索树的特性 二叉搜索树由于其独特的数据结构,使得其无论在增删,还是查找,时间复杂度都是O(h),h为二叉树的高度.因此二叉树应该尽量的矮,即左右节点尽量平衡. 二叉搜索树的构造 要构造二叉搜索树,首先要构造二叉树

javascript数据结构之二叉搜索树实现方法

本文实例讲述了javascript二叉搜索树实现方法.分享给大家供大家参考,具体如下: 二叉搜索树:顾名思义,树上每个节点最多只有二根分叉:而且左分叉节点的值 < 右分叉节点的值 . 特点:插入节点.找最大/最小节点.节点值排序 非常方便 二叉搜索树-javascript实现 <script type="text/javascript"> // <![CDATA[ //打印输出 function println(msg) { document.write(msg

Python实现二叉搜索树

二叉搜索树 我们已经知道了在一个集合中获取键值对的两种不同的方法.回忆一下这些集合是如何实现ADT(抽象数据类型)MAP的.我们讨论两种ADT MAP的实现方式,基于列表的二分查找和哈希表.在这一节中,我们将要学习二叉搜索树,这是另一种键指向值的Map集合,在这种情况下我们不用考虑元素在树中的实际位置,但要知道使用二叉树来搜索更有效率. 搜索树操作 在我们研究这种实现方式之前,让我们回顾一下ADT MAP提供的接口.我们会注意到,这种接口和Python的字典非常相似. Map() 创建了一个新的

二叉搜索树的插入与删除(详细解析)

题目:创建一个类,类中的数据成员时一棵二叉搜索树,对外提供的接口有添加结点和删除结点这两种方法.用户不关注二叉树的情况.要求我们给出这个类的结构以及实现类中的方法. 思路添加结点:添加结点其实很容易,我们只需要找到结点所行对应的位置就可以了,而且没有要求是平衡的二叉搜索树,因此每次添加结点都是在叶子结点上操作,不需要修改二叉搜索树整体的结构.要找出添加节点在二叉搜索树中的位置,可以用一个循环解决.判断插入结点与当前头结点的大小,如果大于头结点则继续搜索右子树,如果小于头结点则继续搜索左子树.直到

C++ 二叉搜索树(BST)的实现方法

废话不多说了,直接给大家贴代码了,具体代码如下所示: class BST { public: struct Node { int key;//节点的key int value;//节点的value Node* left; Node *right; int N;//节点的叶子节点数目 Node(int _key, int _value, int _N) { key = _key; value = _value; N = _N; } }; BST(); ~BST(); void put(int ke

C#创建二叉搜索树的方法

本文实例讲述了C#创建二叉搜索树的方法.分享给大家供大家参考.具体如下: public static BinaryTreeNode BuildBinarySearchTree(int[] sortedArray) { if (sortedArray.Length == 0) return null; int _mid = sortedArray.Length / 2; BinaryTreeNode _root = new BinaryTreeNode(sortedArray[_mid]); in

Java 实现二叉搜索树的查找、插入、删除、遍历

由于最近想要阅读下JDK1.8 中HashMap的具体实现,但是由于HashMap的实现中用到了红黑树,所以我觉得有必要先复习下红黑树的相关知识,所以写下这篇随笔备忘,有不对的地方请指出- 学习红黑树,我觉得有必要从二叉搜索树开始学起,本篇随笔就主要介绍Java实现二叉搜索树的查找.插入.删除.遍历等内容. 二叉搜索树需满足以下四个条件: 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 任意节点的左.右子

二叉搜索树实例练习

一棵二叉查找树是按二叉树结构来组织的.这样的树可以用链表结构表示,其中每一个结点都是一个对象.结点中除了数据外,还包括域left,right和p,它们分别指向结点的左儿子.右儿子,如果结点不存在,则为NULL. 它或者是一棵空树:或者是具有下列性质的二叉树: 1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值: (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值: (3)左.右子树也分别为二叉查找树: 显然满足了上面的性质,那么二叉查找树按中序遍历就是按从小到大的顺序遍历,