@leetcode對稱二叉樹
作為一道稍有高階的資料結構經典題,對稱二叉樹的使用著實費了小白筆者不少腦筋。我一直在想能不能用先序後序遍歷的方法解決,即在一棵樹上做出判斷,然而實際上解法並非如此。賣個關子,請看題幹:
給定乙個二叉樹,檢查它是否是映象對稱的。
例如,二叉樹 [1,2,2,3,4,4,3] 是對稱的。
下面這個 [1,2,2,null,3,null,3] 則不是映象對稱的:
說明:如果你可以運用遞迴和迭代兩種方法解決這個問題,會很加分。
雖然說題目已經暗示了有兩種方法解決這個問題——遞迴和迭代,但是筆者腦子依然是一團漿糊,先入為主的思想真是十分該死,那麼到頭來到底這題的遞迴解法應該怎麼寫?請看**:
剛看到這個想法的時候,筆者確實也不得其要領,但是當你把一棵樹當成兩棵樹來看待,這就不一樣了。
要解決這棵樹是否是對稱的,我們首先要了解映象對稱,又稱手性對稱的概念。這種對稱模型就像你照鏡子,或者你的兩隻手一樣,是相對另一半的反方向對稱的,即在鏡子裡的你的右邊是你的左邊,在鏡子裡的你的左邊是你的右邊。
那麼同理,如果要這棵樹是對稱的,不妨創造另外一棵在鏡子裡的樹,只要原有的這棵樹的左子樹與映象樹的右子樹完全相同,映象樹的左子樹也與原有的樹的右子樹相同,並且根結點相同,說明這棵樹確實是對稱的。
那麼總結一下就是需要滿足兩個條件:第一,兩棵樹的根結點必須相同(可以同時為空,說明是一棵空樹);第二,對應方向的左子樹必須與右子樹完全相等(右子樹與左子樹完全相等)。當這兩個條件同時滿足的時候就可以解決問題。
與之對應的**如上,需要注意的是,要先判斷返回true的雙空情況,再判斷其中乙個為空的情況,因為雙空情況不是已經都沒有子樹了就是整個為空樹,這兩種情況是一定可得證為正確情況的,而其中乙個為空,就如第二個示例,是不可能正確的。再這兩種情況都不滿足的時候就是比較環節了,與之前判斷相同的樹時類似,使用短路運算能節省很多的運算步驟和不需要的**:如果兩個結點相等,這也是必須滿足的第乙個條件,再進行判斷接下來的遞迴條件,必選其一,最終得到答案。
那麼還有一種迭代的方法呢?說實話,其實迭代的方法認真思考之下是更容易想到的,無非就是我開兩個佇列,分別儲存兩個子樹的每乙個子節點並按順序pop比較一下,請看**:
迭代法參上!確實開了兩個佇列解決問題(實際上乙個佇列也能解決,只是開兩個要明晰一些),要注意佇列的定義和幾個方法的使用,筆者在這上面ce了好多次,注意pop金近是出隊頭元素,並不能取得頭元素的值。後面push的順序一定要注意,要按照正確的比較順序push這一層的結點才能起到比較映象的作用。值得一提的是,最後有乙個返回true可別丟了,否則正確的情況會在迴圈裡不停地continue出不來,那是真的很尷尬。
leetcode 二叉樹 對稱二叉樹
給定乙個二叉樹,檢查它是否是映象對稱的。例如,二叉樹 1,2,2,3,4,4,3 是對稱的。1 2 2 3 4 4 3 但是下面這個 1,2,2,null,3,null,3 則不是映象對稱的 1 2 2 3 3 方法一 遞迴 思路 如果乙個樹的左子樹與右子樹映象對稱,則該樹是對稱的 兩個樹互為映象的...
LeetCode 對稱二叉樹
給定乙個二叉樹,檢查它是否是映象對稱的。例如,二叉樹 1,2,2,3,4,4,3 是對稱的。1 2 2 3 4 4 3但是下面這個 1,2,2,null,3,null,3 則不是映象對稱的 1 2 2 3 3class solution public boolean issymmetricdoubl...
LeetCode 對稱二叉樹
我的解決方案 比較笨拙,我直接按照左後根遍歷一遍,然後再按照右後根遍歷一遍,最後比較結果 class treenode public class solution string ltreetostring tree.left,string string ltreetostring tree.righ...