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

这又双叒是一道之前算法课水过的但现在还是不会做的题orz 题目要求很简单,就是判断两棵树是不是一样的。如果要判断两棵树是否相同,那么就从root开始一个个判断它们的数字是否相等。在判断数字是否相等之前还可以判断它们的结构,如果一棵为空、另一棵有子节点,那么它们就必然不相同。可以通过递归来解决这个问题:如果两个节点存在为NULL的,那就返回两个节点是否相同,如果相同则两个都是NULL,为true,否则不同就要返回false,通过这样一句可以减少if-else的使用。如果两个节点不为NULL,那么就需要比较这两个节点的value是否相同,以及以这两个节点为root的子树是否相同,这就是递归的用法了。代码如下,运行时间0ms:

/**
 * 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) {
        if (!p || !q) {
            return (p == q);
        }
        else {
            bool left = isSameTree(p->left, q->left);
            bool right = isSameTree(p->right, q->right);
            if ((p->val == q->val) && left && right) {
                return true;
            }
            else {
                return false;
            }
        }
    }
};

2020.10.06 Java:

会写了。复杂度O(n)。

Runtime: 0 ms, faster than 100.00% of Java online submissions for Same Tree.

Memory Usage: 36.4 MB, less than 91.84% of Java online submissions for Same Tree.

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p == null || q == null) {
            return p == q;
        }
        if (p.val != q.val) {
            return false;
        } else {
            return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
        }
    }
}

2023.1.2

嗯还是秒写出来了递归,写法和以前略微不同。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p == null && q == null) {
            return true;
        } else if (p == null || q == null) {
            return false;
        }
        return p.val == q.val && isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }
}

除此之外,还看到一个非递归的做法,大意就是采用一个stack来存储每一个节点的左、右两个节点,类似于前序遍历。从根节点开始,把两棵树的根节点push进栈,然后从根节点往下,每次pop最后的两个节点出来比较它们是否相同,如果相同,则可以把这个节点的左右子节点push进栈,继续进行比较,直到栈为空,或者pop出来的两个节点的value不同,返回false。代码如下,运行时间0ms:

/**
 * 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*> stk;
        stk.push(p);
        stk.push(q);
        
        while (!stk.empty()) {
            TreeNode* first = stk.top();
            stk.pop();
            TreeNode* second = stk.top();
            stk.pop();
            
            if (!first && !second) {
                continue;
            }
            else if (!first || !second || (first->val != second->val)) {
                return false;
            }
            else {
                stk.push(first->left);
                stk.push(second->left);
                stk.push(first->right);
                stk.push(second->right);
            }
        }
        return true;
    }
};

2020.10.12 Java:

迭代写法感觉有点像dfs/bfs,找一种方式遍历它,我用了两个stack做dfs,每次取出stack top的元素比较它俩value是否相等。在push他们的子节点的时候需要注意,因为java中Deque是不允许存在null节点的(Queue是可以的),所以要先判断左右子节点是否存在,并且如果是一个存在但另一个不存在的话就直接return false,如果两个都不存在的话可以继续往下走。其实好像一个stack也可以做,每次成双成对地往里push,然后pop也是pop两个出来进行比较就可以了。

Runtime: 0 ms, faster than 100.00% of Java online submissions for Same Tree.

Memory Usage: 36.4 MB, less than 15.96% of Java online submissions for Same Tree.

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p == null || q == null) {
            return p == q;
        }
        Deque<TreeNode> stack1 = new ArrayDeque<>();
        Deque<TreeNode> stack2 = new ArrayDeque<>();
        stack1.push(p);
        stack2.push(q);
        while (!stack1.isEmpty() && !stack2.isEmpty()) {
            TreeNode node1 = stack1.pop();
            TreeNode node2 = stack2.pop();
            if (node1.val != node2.val) {
                return false;
            }
            if (node1.left != null && node2.left != null) {
                stack1.push(node1.left);
                stack2.push(node2.left);
            } else if (node1.left != node2.left) {
                return false;
            }
            if (node1.right != null && node2.right != null) {
                stack1.push(node1.right);
                stack2.push(node2.right);
            } else if (node1.right != node2.right) {
                return false;
            }
        }
        return true;
    }
}

2023.1.2

瞄到了之前写的代码知道可以用两个deque来存以后,就轻松写出了代码,和之前一样,只是忘了可以直接比较node1.left != node2.left来判断当node1和node2至少有一个为null时他们一不一样。

然后试了只用一个stack的做法,嗯,其实是完全一样的,代码都不用改多少,其实就是多年前用C++写的那会儿记的那个方法。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p == null || q == null) {
            return p == q;
        }
        Deque<TreeNode> stack = new ArrayDeque<>();
        stack.push(p);
        stack.push(q);
        while (!stack.isEmpty()) {
            TreeNode node1 = stack.pop();
            TreeNode node2 = stack.pop();
            if (node1.val != node2.val) {
                return false;
            }
            if (node1.left != null && node2.left != null) {
                stack.push(node1.left);
                stack.push(node2.left);
            } else if (node1.left != node2.left) {
                return false;
            }
            if (node1.right != null && node2.right != null) {
                stack.push(node1.right);
                stack.push(node2.right);
            } else if (node1.right != node2.right) {
                return false;
            }
        }
        return true;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值