# LeetCode 解題筆記 (Tree類型題目) 解題時要注意的重點 1. 一題多解,找不同的思維;可以看討論區的解題方法 2. 不要盲目刷題,至少要帶走一些想法 3. 精通一種解法;某些題型適合某一種演算法,可以做統整 4. 定義題目內容與輸出的結果;例如考官到底要什麼;題目給的例子是不是分類過的array ![](https://i.imgur.com/OGke5Sr.png) ![](https://i.imgur.com/rqE3iHd.png) [影片來源](https://www.youtube.com/watch?v=NdWYxz3izH4) ## [難度Easy] 類型:Tree ### 100. Same Tree [題目網址](https://leetcode.com/problems/same-tree) > 提供一個建構子,該建構子會製造名為left、right的節點跟本身的值,請判斷提供的兩個節點p、q是不是同一個節點 > #### 解法1 ``` var isSameTree = function(p, q) { if(!p && !q) return true if(!p || !q || p.val !== q.val) return false return isSameTree(p.left,q.left) && isSameTree(p.right,q.right) }; ``` 看起來很像需要無窮迴圈的檢查,沒有什麼頭緒,想了一陣子想不出來所以找了[別人的解法](https://leetcode.com/problems/same-tree/discuss/32935/JavaScript-solution);概念是如果沒有p跟q,那代表兩者相同,接著如果沒有p或q或兩者的值不同,那代表不相同,接著回傳該函式去檢查左右node #### 解法2 ``` var isSameTree = function(p, q) { if(p===null) return q===null; if(q===null) return p===null; if(p.val!==q.val) return false; return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); }; ``` 概念同上,但比較好理解 [來源](https://leetcode.com/problems/same-tree/discuss/32882/4-lines-javascript) [另一種類似解法](https://skyyen999.gitbooks.io/-leetcode-with-javascript/content/questions/100md.html) ### 101. Symmetric Tree [題目網址](https://leetcode.com/problems/symmetric-tree/) > 提供一個建構子,該建構子會製造名為left、right的節點跟本身的值,請判斷提供的節點是不是呈現對稱排列 ![](https://i.imgur.com/Zzlp6d3.png) > #### 方法1 ``` var isSymmetric = function(root) { if(!root) return true return isLeftRightAreSame(root.right,root.left) }; function isLeftRightAreSame(r,l){ if(!r && !l) return true if(!r || !l || r.val !== l.val) return false return isLeftRightAreSame(l.right,r.left) && isLeftRightAreSame(l.left,r.right) } ``` 概念同 100.Same Tree,都是要把節點放入迴圈內檢查 #### 方法2 ``` var isSymmetric = function(root) { if(!root) return true const right = [root.right], left = [root.left] while(right.length && left.length){ const i = right.pop(), j = left.pop() if(!i && !j) continue if(!i || !j || i.val !== j.val) return false right.push(i.left,i.right) left.push(j.right,j.left) } return true }; ``` 把左右節點放到right、left陣列中,接著拿出來檢查,檢查完之後,把相對應要檢查的節點依照順序放入,如果檢查完都沒出錯,那就是對稱的節點。 [想法來源](https://leetcode.com/problems/symmetric-tree/discuss/33073/JavaScript-recursive-and-iterative-solutions) #### 方法3 ``` var isSymmetric = function(root) { if(root == null || (root.right == null && root.left == null) ){ return true; } // 先將right反轉,再比對是否相等 root.right = revertTree(root.right); return isSameTree(root.left,root.right); // 反轉樹 function revertTree(node){ if(node == null || node.left == null && node.right == null){ return node; } var temp = revertTree(node.left); node.left = revertTree(node.right); node.right = temp; return node; } // 比對是否相等 function isSameTree(left,right){ if(left == null && right== null){ return true; } if(left == null && right != null || right == null &&left != null){ return false; } if(left.val != right.val){ return false; } return isSameTree(left.right, right.right) && isSameTree(left.left, right.left) } }; ``` 把節點內容翻轉過來,再檢查是不是相同 [來源](https://skyyen999.gitbooks.io/-leetcode-with-javascript/content/questions/101md.html) ### 104. Maximum Depth of Binary Tree [題目網址](https://leetcode.com/problems/maximum-depth-of-binary-tree/) > 提供一個建構子,該建構子會製造名為left、right的節點跟本身的值,請判斷提供的節點最大長度 ![](https://i.imgur.com/gr18nYr.png) #### 方法1 ``` var maxDepth = function(root) { return root ? 1 + Math.max(maxDepth(root.right),maxDepth(root.left)) : 0 }; ``` 如果沒有root結點,回傳0,有的話,至少有1,接著找左右節點最大長度,這邊要使用迭代的方式來尋找 #### 方法2 ``` var maxDepth = function(root) { return find(root) }; function find(n){ if(!n) return 0 let right = 1, left = 1 if(n.right) right += find(n.right) if(n.left) left += find(n.left) return Math.max(right,left) } ``` 同方法1,首先有root,那節點就為1,接著宣告right,left總共的節點數量為1,如果能繼續找到節點就加上去,最後看左右哪邊比較大 [來源](https://skyyen999.gitbooks.io/-leetcode-with-javascript/content/questions/104md.html) ###### tags: `LeetCode` `Tree` `easy`