對稱二叉樹

唯愛程式設計發表於2021-02-27

題目

給定一個二叉樹,檢查它是否是映象對稱的。

例如,二叉樹[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

解法

解法一: 遞迴。

/**
 * 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 isSymmetric(TreeNode root) {
        if(root == null){
            return true;
        }
        TreeNode left = root.left;
        TreeNode right = root.right;
        return isSymmetricForLeftAndRight(left,right);
    }

    // 判斷left和right是否對稱
    public boolean isSymmetricForLeftAndRight(TreeNode left,TreeNode right){
        if(left == null || right == null){
            if(left != null || right != null){
                return false;
            } else {
                return true;
            }
        }
        // 判斷值是否相等
        int leftVal = left.val;
        int rightVal = right.val;
        if(leftVal != rightVal){
            return false;
        }

        // 遞迴呼叫,判斷左節點的左節點與右節點的右節點是否對稱
        TreeNode leftNextLeft = left.left;
        TreeNode rightNextRight = right.right;
        if(!isSymmetricForLeftAndRight(leftNextLeft,rightNextRight)){
            return false;
        }

        // 遞迴呼叫,判斷左節點的右節點與右節點的左節點是否對稱
        TreeNode leftNextRight = left.right;
        TreeNode rightNextLeft = right.left;
        if(!isSymmetricForLeftAndRight(leftNextRight,rightNextLeft)){
            return false;
        }

        return true;
    }
}

解法二: 迭代

/**
 * 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 isSymmetric(TreeNode root) {
        if(root == null){
            return true;
        }
        // 建立佇列,特點是先進先出。
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root.left);
        queue.offer(root.right);

        while(!queue.isEmpty()){
            TreeNode left = queue.poll();
            TreeNode right = queue.poll();
            if(left == null || right == null){
                if(left != null || right != null){
                    return false;
                } else {
                    continue;
                }
            }
            int leftVal = left.val;
            int rightVal = right.val;
            if(leftVal != rightVal){
                return false;
            }
            
            // 再把left和right子節點放進去,注意順序
            // 順序一定是left的左節點和right的右節點,然後是left的右節點和right的左節點
            queue.offer(left.left);
            queue.offer(right.right);
            queue.offer(left.right);
            queue.offer(right.left);
        }

        return true;
    }
}

總結

本篇文章講解了演算法題目的思路和解法,程式碼和筆記由於純手打,難免會有紕漏,如果發現錯誤的地方,請第一時間告訴我,這將是我進步的一個很重要的環節。以後會定期更新演算法題目以及各種開發知識點,如果您覺得寫得不錯,不妨點個關注,謝謝。

相關文章