本專題旨在分享刷Leecode過程發現的一些思路有趣或者有價值的題目。【當然是基於js進行解答】。
遞迴演算法一直是leetcode 中等難度習題的重點型別之一,所以關鍵性不言而喻。
題目相關
- 原題地址: https://leetcode-cn.com/problems/dui-cheng-de-er-cha-shu-lcof/
題目描述:
請實現一個函式,用來判斷一棵二叉樹是不是對稱的。如果一棵二叉樹和它的映象一樣,那麼它是對稱的。
例如,二叉樹 [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
Tips
考慮某些同學可能比較少用js來刷leetcode,我們在這裡簡單介紹下,關於樹型別的資料輸入,在js裡的表示。 形如上題中的內容,給定二叉樹的輸入,其實並非一個陣列,而應該是如下所示: 每個節點是一個object
:
const root = {
val: 3,
left: { // left表示當前節點的左側子節點
val: 9,
left: null, // 對照上圖可以看到 節點9沒有左右子節點
right: null,
},
right: {
val: 20,
left: {
val: 15, // 對照上圖可以看到 節點15沒有左右子節點
left: null,
right: null,
},
right: {
val: 7, // 對照上圖可以看到 節點7沒有左右子節點
left: null,
right: null,
},
}
}
思路解析
首先這道題是明顯的遞迴類題目, 而遞迴類的題目一般就是以下幾個步驟:
- 提取遞迴部分的邏輯
- 判斷邊界條件
- 首先整體的邏輯上, 要判定一棵樹是映象二叉樹的話,肯定是要從根節點的左右節點開始進行對比,在遍歷過程遇到的每一組節點(用L和R表示),都要滿足L的左節點 = R的右節點 且 L的右節點 = R的左節點 由於會遞迴比較,所以這裡相等其實就只要是
val
值相等: 其次是考慮邊界條件
- 如果初始是一顆空的樹,那直接返回結果,也算對稱;
- 同步比對時,在任意一步,只要出現不滿足L的左節點 = R的右節點 且 L的右節點,= R的左節點 ,則提前結束,返回false;
- 如果能夠比對到兩邊同時結束,那麼說明是對稱樹,返回true;
那麼按照前文說的,先寫出遞迴部分的邏輯:
var recuCompare = function (L, R) {
if(!L && !R) { // 說明同時比對同時結束 或者是兩邊均無該子節點
return true;
}
if(!L || !R || L.val !== R.val ) { // 扣除第一種情況 那麼!L 或者 !R說明左右不同時結束,也就是出現不對稱
return false;
}
return recuCompare(L.left, R.right) && recuCompare(L.right, R.left); // 繼續往下比對
}
那麼補上遞迴起始條件部分,完整程式碼就可以得出了。
完整程式碼
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isSymmetric = function(root) {
if(!root) {return true};
return recuCompare(root.left, root.right)
};
var recuCompare = function (L, R) {
if(!L && !R) {
return true;
}
if(!L || !R || L.val !== R.val ) {
return false;
}
return recuCompare(L.left, R.right) && recuCompare(L.right, R.left);
}
有沒有發現,遞迴類題目最後都是程式碼寫出來後不長,但是理解比較吃力,所以更需要自己嘗試著去抓邏輯重點。
很建議大家在看完之後,自己手寫一次程式碼跑跑看
很建議大家在看完之後,自己手寫一次程式碼跑跑看
很建議大家在看完之後,自己手寫一次程式碼跑跑看
因為很多邊界條件的寫法和細節,其實才是除錯過程中最經常出bug的。
另外,大家可以利用本題的思路,去試著解一下 這道遞迴回溯的題目--樹的子結構 從而鞏固所學 https://leetcode-cn.com/probl...
那麼,簡簡單單一道題又搞定了!