劍指 Offer 28. 對稱的二叉樹
知識點:二叉樹;遞迴
題目描述
請實現一個函式,用來判斷一棵二叉樹是不是對稱的。如果一棵二叉樹和它的映象一樣,那麼它是對稱的。
示例
輸入:root = [1,2,2,3,4,4,3]
輸出:true
輸入:root = [1,2,2,null,3,null,3]
輸出:false
解法一:遞迴法
函式功能:判斷樹是否對稱
1.終止條件:left和right都為null,return true;
2.最小單元節點做什麼:判斷是否對稱唄:如果有一方到null另一方沒到 return false; 如果left和right值不等,return false,判斷left的left和right的right是否平衡,判斷left的right和right的left是否平衡;
3.什麼時候做:開始遍歷的時候就可以去判斷了,放在先序的位置上。
我們如何定義兩棵子樹 a 和 b 是否 “對稱” ?
當且僅當兩棵子樹符合如下要求時,滿足 “對稱” 要求:
- 1.兩棵子樹根節點值相同;
- 2.兩顆子樹的左右子樹分別對稱,包括:
- a 樹的左子樹與 b 樹的右子樹相應位置的值相等
- a 樹的右子樹與 b 樹的左子樹相應位置的值相等
遞迴終止條件:
- 1.兩邊都走到樹頭了,而且L.val = R.val = null, return true;
- 2.有一邊走到頭了,即有一個節點為空,L.val == null || R.val == null, return false;
- 3.兩個子樹的值不相等,下面就不用比了,直接false;L.val != R.val, return false;
其他情況,說明在這一層上已經相等了,我們則要分別檢查 L 和 R 的左右節點是否 “對稱” ,即遞迴呼叫 check(L.left, R.right) 和 check(L.right, R.left)
遞迴還是抓住兩點本質:
- 遞迴的終止條件:上面說的那3條;
- 函式的功能是幹什麼的,縮小範圍:函式就是用來比較兩個樹是否對稱的,往裡傳樹就行了,我能得到結果;從上往下,想要知道整個樹是否對稱需要知道左右子樹是否對稱,這是去的過程;知道了左右子樹是否對稱那就能知道大樹是否對稱了,這是回的過程。
/**
* 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;
else{
return isSymmetric(root.left, root.right);
}
}
private boolean isSymmetric(TreeNode left, TreeNode right){
if( left == null && right == null) return true;
if( left == null || right == null) return false;
if( left.val != right.val) return false;
return isSymmetric(left.left, right.right) && isSymmetric(left.right, right.left);
}
}
時間複雜度;0(N),每個節點恰好被遍歷一次;
空間複雜度;O(N),遞迴過程中棧的開銷;