101. Symmetric Tree

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

For example, this binary tree [1,2,2,3,4,4,3] is symmetric:

      1
     / \
    2   2
   / \ / \
  3  4 4  3

But the following [1,2,2,null,3,null,3] is not:

    1
   / \
  2   2
   \   \
   3    3

Note:
Bonus points if you could solve it both recursively and iteratively.

這道題一開(kāi)始不知道如何下手,每次遇到這種需要比較結(jié)構(gòu)的題,心里知道肯定是用遞歸比較簡(jiǎn)單,但自己沒(méi)見(jiàn)過(guò)的題還是不知道該怎么開(kāi)始,比如這里我到底要怎么去比較他們是不是對(duì)稱,那豈不是要比較完每個(gè)節(jié)點(diǎn)的值以及左右子樹(shù)?總之找不到一個(gè)很連貫的思路,或者說(shuō)對(duì)遞歸函數(shù)的結(jié)構(gòu)、寫(xiě)法太不熟練,導(dǎo)致形不成體系,沒(méi)有通用的方法可以破題。

看了答案之后一是覺(jué)得自己怎么這么笨就沒(méi)想到可以這樣做,二是覺(jué)得這類(lèi)題肯定是有通法的,比如這里的遞歸就是讓你判斷哪些情況肯定不是sysmmetric的,一一返回false, 剩下的肯定就是symmetric的了;

先是recursive的解法:

helper函數(shù)用來(lái)判斷左右子樹(shù)是否對(duì)稱。如果兩邊都為空,是對(duì)稱的(可以通過(guò)test case自己看到)。然后看幾個(gè)不對(duì)稱的情況:

  • 一邊為空,一邊不為空,不對(duì)稱;
  • 兩邊的val不一樣,不對(duì)稱;
  • 左邊根節(jié)點(diǎn)的左子樹(shù)與右邊根節(jié)點(diǎn)的右子樹(shù)不對(duì)稱,不對(duì)稱
  • 左邊根節(jié)點(diǎn)的右子樹(shù)與右邊根節(jié)點(diǎn)的左子樹(shù)不對(duì)稱,不對(duì)稱

這里構(gòu)造遞歸函數(shù)的時(shí)候最關(guān)鍵的就是后兩種情況,能把它想清楚想明白這個(gè)recursion基本就能寫(xiě)出來(lái)了。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if (root == null){
            return true;
        }
        return helper(root.left, root.right);
        
    }
    
    private boolean helper(TreeNode l, TreeNode r){
        if (l == null && r == null){
            return true;
        } else if (l == null || r == null){
            return false;
        }
        if (l.val != r.val){
            return false;
        }
        if (!helper(l.left, r.right)){
            return false;
        }
        if (!helper(l.right, r.left)){
            return false;
        }
        return true;
    }
}

這道題還可以用迭代法做:用兩個(gè)queue做BFS來(lái)遍歷左右子樹(shù). 每一次poll()出來(lái),用幾個(gè)條件來(lái)判斷是否對(duì)稱:

  • 一個(gè)為空,一個(gè)不為空,肯定不對(duì)稱;
  • 兩個(gè)poll()出來(lái)的元素值不同,不對(duì)稱;

注意之后每次offer進(jìn)queue,左右兩邊的順序要?jiǎng)偤孟喾矗@樣才能每次poll()出來(lái)的時(shí)候比較是否相等。 最后退出while循環(huán)后,還要判斷是不是只有一個(gè)queue是empty,如果是那說(shuō)明也是不對(duì)稱的。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if (root == null){
            return true;
        }
        Queue<TreeNode> queueLeft = new LinkedList<>();
        Queue<TreeNode> queueRight = new LinkedList<>();
        queueLeft.offer(root);
        queueRight.offer(root);
        while (!queueLeft.isEmpty() && !queueRight.isEmpty()){
            TreeNode nodeLeft = queueLeft.poll();
            TreeNode nodeRight = queueRight.poll();
            if (nodeLeft == null && nodeRight == null){
                continue;
            } else if (nodeLeft == null || nodeRight == null){
                return false;
            }
            if (nodeLeft.val != nodeRight.val){
                return false;
            }
            queueLeft.offer(nodeLeft.left);
            queueLeft.offer(nodeLeft.right);
            queueRight.offer(nodeRight.right);
            queueRight.offer(nodeRight.left);
        }
        if (!queueLeft.isEmpty() || !queueRight.isEmpty()){
            return false;
        }
        return true;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容