Leetcode100 相同的樹
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/same-tree/
博主Github:https://github.com/GDUT-Rp/LeetCode
題目:
給定兩個二叉樹,編寫一個函數來檢驗它們是否相同。
如果兩個樹在結構上相同,並且節點具有相同的值,則認爲它們是相同的。
示例 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
解題思路:
方法一:遞歸算法
直觀想法
最簡單的策略是使用遞歸。首先判斷 p
和 q
是不是 None
,然後判斷它們的值是否相等。
若以上判斷通過,則遞歸對子結點做同樣操作。
C++
/**
* 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_LeetCode100 {
public:
bool isSameTree(TreeNode *p, TreeNode *q) {
if (nullptr == p and q == nullptr) return true;
if (nullptr == p || nullptr == q) return false;
if (p->val != q->val) return false;
return isSameTree(p->left, q->left) and isSameTree(p->right, q->right);
}
};
Java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
// p and q are both null
if (p == null && q == null) return true;
// one of p and q is null
if (q == null || p == null) return false;
if (p.val != q.val) return false;
return isSameTree(p.right, q.right) &&
isSameTree(p.left, q.left);
}
}
Python
# -*- coding: utf-8 -*-
# @File : LeetCode100.py
# @Author : Runpeng Zhang
# @Date : 2020/2/19
# @Desc : 判斷兩顆二叉樹是否相同
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
if p is None and q is None:
return True
if p is None or q is None:
return False
if p.val != q.val:
return False
return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
複雜度分析
時間複雜度:,其中 N 是樹的結點數,因爲每個結點都訪問一次。
空間複雜度:最優情況(完全平衡二叉樹)時爲 ,最壞情況下(完全不平衡二叉樹)時爲 ,用於維護遞歸棧。
方法二:迭代
直觀想法
從根節點開始,每次迭代彈出當前棧頂元素,插入到第一位中,並將其孩子節點壓入棧中,先壓左孩子再壓右孩子。
C++
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
#include <deque>
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if (p == NULL and q == NULL) return true;
if (!check(p, q)) return false;
// init deuqes
deque<TreeNode *> deqP, deqQ;
deqP.push_back(p);
deqQ.push_back(q);
while (!deqP.empty()) {
p = deqP.front();
deqP.pop_front();
q = deqQ.front();
deqQ.pop_front();
if (!check(p, q)) return false;
if (p != NULL) {
if (!check(p->left, q->left)) return false;
if (p->left != NULL) {
deqP.push_back(p->left);
deqQ.push_back(q->left);
}
if (!check(p->right, q->right)) return false;
if (p->right != NULL) {
deqP.push_back(p->right);
deqQ.push_back(q->right);
}
}
}
return true;
}
bool check(TreeNode *p, TreeNode *q) {
if (p == NULL and q == NULL) return true;
if (p == NULL or q == NULL) return false;
if (p->val != q->val) return false;
return true;
}
};
Java
class Solution {
public boolean check(TreeNode p, TreeNode q) {
// p and q are null
if (p == null && q == null) return true;
// one of p and q is null
if (q == null || p == null) return false;
if (p.val != q.val) return false;
return true;
}
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (!check(p, q)) return false;
// init deques
ArrayDeque<TreeNode> deqP = new ArrayDeque<TreeNode>();
ArrayDeque<TreeNode> deqQ = new ArrayDeque<TreeNode>();
deqP.addLast(p);
deqQ.addLast(q);
while (!deqP.isEmpty()) {
p = deqP.removeFirst();
q = deqQ.removeFirst();
if (!check(p, q)) return false;
if (p != null) {
// in Java nulls are not allowed in Deque
if (!check(p.left, q.left)) return false;
if (p.left != null) {
deqP.addLast(p.left);
deqQ.addLast(q.left);
}
if (!check(p.right, q.right)) return false;
if (p.right != null) {
deqP.addLast(p.right);
deqQ.addLast(q.right);
}
}
}
return true;
}
}
Python
# -*- coding: utf-8 -*-
# @File : LeetCode100.py
# @Author : Runpeng Zhang
# @Date : 2020/2/19
# @Desc : 判斷兩顆二叉樹是否相同
from collections import deque
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
"""
:type p: TreeNode
:type q: TreeNode
:rtype: bool
"""
def check(p, q):
# if both are None
if not p and not q:
return True
# one of p and q is None
if not q or not p:
return False
if p.val != q.val:
return False
return True
deq = deque([(p, q), ])
while deq:
p, q = deq.popleft()
if not check(p, q):
return False
if p:
deq.append((p.left, q.left))
deq.append((p.right, q.right))
return True
算法複雜度:
時間複雜度:訪問每個節點恰好一次,時間複雜度爲 ,其中 是節點的個數,也就是樹的大小。
空間複雜度:取決於樹的結構,最壞情況存儲整棵樹,因此空間複雜度是 。