Leetcode 100. 相同的树

1.题目描述

给定两个二叉树,编写一个函数来检验它们是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例 1:

输入:       1         1
          /        / 
         2   3     2   3

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

输出: true

示例 2:

输入:      1          1
          /           
         2             2

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

输出: false

示例 3:

输入:       1         1
          /        / 
         2   1     1   2

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

输出: false

  

2.解法一:递归

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        //先序遍历-递归
        if((p==NULL && q) || (p && q==NULL)) return false;
        if(p && q && p->val!= q->val) return false;
        
        //两颗子树同时为真才真
        if(p && q) return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
        return true;     
    }
};

3.解法二:非递归--栈(先序遍历)

3.1 使用2个栈

  • 我的粗糙代码
/**
* Definition for a binary tree node.
* struct TreeNode {
*     int val;
*     TreeNode *left;
*     TreeNode *right;
*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {

        stack<TreeNode*> s1;
        stack<TreeNode*> s2;

        //true的情况1
        if (p == NULL && q == NULL) return true;

        if (p && q == NULL) return false;
        if (p == NULL && q) return false;
        if (p->val != q->val) return false; //测试用例:[0]和[1]

        //true的情况2
        while (p || !s1.empty())
            //循环结束条件,选定p作为基准
        {
//先序遍历
if (p){ s1.push(p); p = p->left; } else{ p = s1.top(); s1.pop(); p = p->right; } if (q){ s2.push(q); q = q->left; } else{ q = s2.top(); s2.pop(); q = q->right; } if ((p == NULL && q) || (p && q == NULL)) return false; if (p && q && p->val != q->val) return false; } return true; } };

3.2 使用1个栈

  • 更加精巧的解法,来源于Leetcode上提交的代码
class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        stack<TreeNode*> s;
        s.push(p);
        s.push(q);
    
        while(!s.empty())
        {
            p = s.top();
            s.pop();
            
            q = s.top();
            s.pop();
            
            if(!p&&!q) continue;
            if(!p||!q) return false;
            
            if(p->val != q->val) return false;
            
            s.push(p->left);
            s.push(q->left);
            
            s.push(p->right);
            s.push(q->right);            
        }
        return true;        
    }
};

4.解法三:非递归--队列(层次遍历)

class Solution {
public:

    static bool isSameTree(TreeNode* p, TreeNode *q) {
        if (p == NULL && q == NULL){
            return true;
        }
        //两种情况合在一起
        else if (p == NULL || q == NULL){
            return false;
        }

        queue<TreeNode*> q1;
        queue<TreeNode*> q2;
        q1.push(p);
        q2.push(q);

        while (!q1.empty() && !q2.empty())
        {
            TreeNode* cur1 = q1.front();
            q1.pop();
            TreeNode* cur2 = q2.front();
            q2.pop();

            if (cur1 == NULL && cur2 == NULL){
                continue;
            }
            else if (cur1 != NULL && cur2 != NULL && cur1->val == cur2->val){
                q1.push(cur1->left);
                q1.push(cur1->right);
                q2.push(cur2->left);
                q2.push(cur2->right);
            }
            else{
                return false;
            }
        }
        return true;
    }
};

5.问题转化:树的序列化-->字符串比较

        另一篇博文:02.树的序列化与反序列化(C++)

//#include <sstream>
class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        string s1 = treeToStr(p);
        string s2 = treeToStr(q);
        return s1==s2;        
    }
    
    
    //------二叉树的序列化----------------
     string treeToStr(TreeNode* head) {
        if (head == NULL) {
            return "#_";
        }
        string res = int2str(head->val) + "_";
        res += treeToStr(head->left);
        res += treeToStr(head->right);
        return res;
    }
    //int to string 
    string int2str(const int &int_temp)
    {
        stringstream stream;
        stream << int_temp;
        string string_temp;
        stream >> string_temp; //stream中转站
        return string_temp;
    }    
};

原文地址:https://www.cnblogs.com/paulprayer/p/10145065.html