[LeetCode] #100 相同的樹
給你兩棵二叉樹的根節點 p
和 q
,編寫一個函式來檢驗這兩棵樹是否相同。
如果兩個樹在結構上相同,並且節點具有相同的值,則認為它們是相同的。
輸入:p = [1,2,3], q = [1,2,3]
輸出:true
二叉樹對比,還是先用遞迴
遞迴有三部曲
(1)找整個遞迴的終止條件:遞迴應該在什麼時候結束? 節點為null
(2)找返回值:應該給上一級返回什麼資訊?兩個子樹是否相同
(3)本級遞迴應該做什麼:在這一級遞迴中,應該完成什麼任務?
如果兩個節點都為空,則相同;其中一個為空,則不相同;都不為空,比較值是否相等,相等繼續比較左子樹和右子樹。
此方法又稱深度優先遍歷/前序遍歷
/** * 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; if (p == null) return false; if (q == null) return false; if (p.val == q.val) return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);else return false; } }
廣度優先遍歷/層次遍歷(非遞迴)
class Solution { public boolean isSameTree(TreeNode p, TreeNode q) { Queue<TreeNode> tmpQueue = new LinkedList<TreeNode>(); tmpQueue.offer(p); tmpQueue.offer(q); while(!tmpQueue.isEmpty()){ p= tmpQueue.poll(); q = tmpQueue.poll(); if(p == null && q == null){ continue; } if((p == null || q == null) || p.val != q.val){ return false; } tmpQueue.offer(p.left); tmpQueue.offer(q.left); tmpQueue.offer(p.right); tmpQueue.offer(q.right); } return true; } }
知識點:
下面是Java中Queue的一些常用方法:
add 新增一個元素 如果佇列已滿,則丟擲一個IIIegaISlabEepeplian異常
remove 移除並返回佇列頭部的元素 如果佇列為空,則丟擲一個NoSuchElementException異常
element 返回佇列頭部的元素 如果佇列為空,則丟擲一個NoSuchElementException異常
offer 新增一個元素並返回true 如果佇列已滿,則返回false
poll 移除並返問佇列頭部的元素 如果佇列為空,則返回null
peek 返回佇列頭部的元素 如果佇列為空,則返回null
put 新增一個元素 如果佇列滿,則阻塞
take 移除並返回佇列頭部的元素 如果佇列為空,則阻塞
總結:
深度優先遍歷:沿著樹的深度遍歷結點,儘可能深的搜尋樹的分支。如果當前的節點所在的邊都被搜尋過,就回溯到當前節點所在的那條邊的起始節點。一直重複直到進行到發現源節點所有可達的節點為止。
廣度優先遍歷:從根節點開始,沿著樹的寬度遍歷樹的節點,直到所有節點都被遍歷完為止。