每日一道 LeetCode (20):相同的樹
阿新 • • 發佈:2020-08-17
每天 3 分鐘,走上演算法的逆襲之路。
前文合集
程式碼倉庫
GitHub: https://github.com/meteor1993/LeetCode
Gitee: https://gitee.com/inwsy/LeetCode
題目:相同的樹
題目來源:https://leetcode-cn.com/problems/same-tree/
給定兩個二叉樹,編寫一個函式來檢驗它們是否相同。
如果兩個樹在結構上相同,並且節點具有相同的值,則認為它們是相同的。
示例 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
解題思路
今天又見到新的資料結構了,這次遇到的是樹,或者簡單的說是二叉樹。
例行慣例,第一次的見的資料結構基本上都沒啥想法,直接看答案。
只能怨自己肚子裡墨水太少,不會的太多,搞不定的只能答案走起,演算法這玩意,答案背多了再遇到題也就有想法了。
先放一段樹的結構程式碼:
public class TreeNode { public int val; public TreeNode left; public TreeNode right; public TreeNode() {} public TreeNode(int val) { this.val = val; } public TreeNode(int val, TreeNode left, TreeNode right) { this.val = val; this.left = left; this.right = right; } }
這段程式碼很簡單,樹上的值是 int 型別,然後有一個左節點有一個右節點。
樹結構介紹完畢,接下來梳理兩種遍歷樹的方案,或者說是常規操作。
解題的話提供兩種方案,一種是遞迴,一種是迴圈。
遞迴
首先極限值判斷,兩個二叉樹都為空肯定相等,如果一個為空另一個不為空肯定不相等。
接下來如果兩個二叉樹都不為空,那麼首先判斷它們的根節點的值是否相同,若不相同則兩個二叉樹一定不同,若相同,再分別判斷兩個二叉樹的左子樹是否相同以及右子樹是否相同,然後接著遞迴這個過程。
迴圈
首先和上面一樣,先進行極限值判斷。
使用兩個佇列分別儲存兩個二叉樹的節點。初始時將兩個二叉樹的根節點分別加入兩個佇列。每次從兩個佇列各取出一個節點,進行操作:
- 比較兩個節點的值,如果兩個節點的值不相同則兩個二叉樹一定不同。
- 如果兩個節點的值相同,則判斷兩個節點的子節點是否為空,如果只有一個節點的左子節點為空,或者只有一個節點的右子節點為空,則兩個二叉樹的結構不同,因此兩個二叉樹一定不同。
- 如果兩個節點的子節點的結構相同,則將兩個節點的非空子節點分別加入兩個佇列,子節點加入佇列時需要注意順序,如果左右子節點都不為空,則先加入左子節點,後加入右子節點。
結果,如果迴圈結束的時候兩個佇列同時為空,那麼這兩個二叉樹相同,如果有一個不為空,那肯定不相同。
程式碼:
// 迭代
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
} else if (p == null || q == null) {
return false;
} else if (p.val != q.val) {
return false;
} else {
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
}
// 迴圈
public boolean isSameTree_1(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (p == null || q == null) return false;
Queue<TreeNode> queue1 = new LinkedList<>();
Queue<TreeNode> queue2 = new LinkedList<>();
queue1.offer(p);
queue2.offer(q);
while (!queue1.isEmpty() && !queue2.isEmpty()) {
TreeNode node1 = queue1.poll();
TreeNode node2 = queue2.poll();
if (node1.val != node2.val) return false;
TreeNode left1 = node1.left, right1 = node1.right, left2 = node2.left, right2 = node2.right;
if (left1 == null ^ left2 == null) return false;
if (right1 == null ^ right2 == null) return false;
if (left1 != null) queue1.offer(left1);
if (right1 != null) queue1.offer(right1);
if (left2 != null) queue2.offer(left2);
if (right2 != null) queue2.offer(right2);
}
return queue1.isEmpty() && queue2.isEmpty();
}
結果我就不貼了,基本上答案區就這麼兩種解題方式,也沒其他能玩出花來的方式。