├── .gitignore ├── README.md ├── SUMMARY.md ├── book.json ├── license.png ├── others.md ├── picture ├── 223.png ├── 237.png ├── 24.png ├── 36.png └── README.md ├── questions ├── 0md.md ├── 100md.md ├── 101md.md ├── 102md.md ├── 104md.md ├── 107md.md ├── 110md.md ├── 111md .md ├── 112md.md ├── 118md.md ├── 119md.md ├── 121md.md ├── 125md.md ├── 13md.md ├── 141md.md ├── 14md.md ├── 155md.md ├── 160md.md ├── 165md.md ├── 168md.md ├── 169md.md ├── 171md.md ├── 172md.md ├── 189md.md ├── 190md.md ├── 191md.md ├── 198md.md ├── 19md.md ├── 1md.md ├── 202md.md ├── 203md.md ├── 204md.md ├── 205md.md ├── 206md.md ├── 20md.md ├── 217md.md ├── 219md.md ├── 21md.md ├── 223md.md ├── 225md.md ├── 226md.md ├── 231md.md ├── 232md.md ├── 234md.md ├── 235md.md ├── 237md.md ├── 242md.md ├── 24md.md ├── 255md.md ├── 257md.md ├── 258md.md ├── 263md.md ├── 26md.md ├── 278md.md ├── 27md.md ├── 283md.md ├── 28md.md ├── 290md.md ├── 292md.md ├── 299md.md ├── 2md.md ├── 303md.md ├── 326md.md ├── 342md.md ├── 344md.md ├── 345md.md ├── 349md.md ├── 350md.md ├── 36md.md ├── 371md.md ├── 374md.md ├── 38md.md ├── 58md.md ├── 66md.md ├── 67md.md ├── 6md.md ├── 70md.md ├── 7md.md ├── 83md.md ├── 88md.md ├── 8md.md ├── 9md.md └── README.md ├── sortbyacceptance.md ├── sortbynumber.md ├── string.md └── styles ├── print.css └── website.css /.gitignore: -------------------------------------------------------------------------------- 1 | # Node rules: 2 | ## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 3 | .grunt 4 | 5 | ## Dependency directory 6 | ## Commenting this out is preferred by some people, see 7 | ## https://docs.npmjs.com/misc/faq#should-i-check-my-node_modules-folder-into-git 8 | node_modules 9 | 10 | # Book build output 11 | _book 12 | 13 | # eBook build output 14 | *.epub 15 | *.mobi 16 | *.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LeetCode with Javascript 2 | 3 | ## by YanQY(驗) at 2016 4 | *** 5 | ## [開始閱讀](https://www.gitbook.com/read/book/skyyen999/-leetcode-with-javascript) 6 | ## [github連結](https://github.com/skyyen999/leetcodeWithJS) 7 | *** 8 | ## 關於LeetCode 9 | LeetCode是一個線上的網站,提供IT人員面試時常常會遇到的現場coding題目, 10 | 這些題目其實是可以透過練習來熟悉理解,在練習的同時,IT人員也可以增進自己coding的能力。LeetCode除了將這些題目 11 | 搬上到網頁上讓使用者可以選擇不同的程式語言進行線上coding之外,也有討論區可以分享或是看其他人解題的思路想法。 12 | 13 | 題目有分為,Easy,Medium,Hard三個等級,每題後面還有目前線上使用者提交程式碼的通過率,一般來說,同樣等級的題目, 14 | 通過率越高的題目為越簡單,這也是我建議的解題順序,先從Easy,通過率最高的一題開始。 15 | 16 | ## 版權許可(License) 17 | 18 | 本書採用創用CC授權4.0 "姓名標示─非商業性─相同方式分享(BY-NC-SA)" 授權。 19 | 20 |  21 | 22 | 本授權條款允許使用者重製、散布、傳輸以及修改著作,但不得為商業目的之使用。若使用者修改該著作時,僅得依本授權條款或與本授權條款類似者來散布該衍生作品。使用時必須按照著作人指定的方式表彰其姓名。 23 | 24 | 詳細資訊請參考[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/)。 25 | 26 | ## 關於這份文件 27 | 一開始練習LeetCode的時候,深深感受到自己coding相關的基礎實在太差,演算法,資料結構等等都還要再加強。 28 | 解題的時候往往想了很久還要去參考別人的寫法才能順利通過測試,但常常我是用大量的試誤法Trail & Error來拼湊出正確的答案, 29 | 對於題目應該要怎麼解沒有一個比較確切的想法,這份文件主要是整理自己解題的方向以及解題過程中的一些心得。 30 | 31 | 目前只包含LeetCode Easy的題目,而且只有免費的部分,目前還沒有打算去解付費的題目,預設排序是通過率從高到低, 32 | 主要目的是盡量清楚明白的解釋為什麼要這樣寫,因此程式碼一定不會很簡潔,執行的速度也不是最快,這點請多多包涵, 33 | 有發現錯誤請到[這邊](https://github.com/skyyen999/leetcodeWithJS/issues/new) 留言,感激不盡。 34 | 35 | ## 作者 36 | #### YanQY 37 | #### mail: skyyen999@gmail.com 38 | #### github: https://github.com/skyyen999 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | * [README](README.md) 3 | * [通過率排序](sortbyacceptance.md) 4 | * [題號排序](sortbynumber.md) 5 | * 字串String 6 | * [LeetCode 344. Reverse String](questions/344md.md) 7 | * [LeetCode 242. Valid Anagram](questions/242md.md) 8 | * [LeetCode 13. Roman to Integer](questions/13md.md) 9 | * [LeetCode 345. Reverse Vowels of a String](questions/345md.md) 10 | * [LeetCode 205. Isomorphic Strings](questions/205md.md) 11 | * [LeetCode 290. Word Pattern](questions/290md.md) 12 | * [LeetCode 38. Count and Say](questions/38md.md) 13 | * [LeetCode 20. Valid Parentheses](questions/20md.md) 14 | * [LeetCode 58. Length of Last Word](questions/58md.md) 15 | * [LeetCode 14. Longest Common Prefix](questions/14md.md) 16 | * [LeetCode 67. Add Binary](questions/67md.md) 17 | * [LeetCode 28. Implement strStr()](questions/28md.md) 18 | * [LeetCode 6. ZigZag Conversion](questions/6md.md) 19 | * [LeetCode 125. Valid Palindrome](questions/125md.md) 20 | * [LeetCode 165. Compare Version Numbers](questions/165md.md) 21 | * [LeetCode 8. String to Integer (atoi)](questions/8md.md) 22 | * 數學Number 23 | * [LeetCode 258. Add Digits](questions/258md.md) 24 | * [LeetCode 171. Excel Sheet Column Number](questions/171md.md) 25 | * [LeetCode 326. Power of Three](questions/326md.md) 26 | * [LeetCode 231. Power of Two](questions/231md.md) 27 | * [LeetCode 202. Happy Number](questions/202md.md) 28 | * [LeetCode 263. Ugly Number](questions/263md.md) 29 | * [LeetCode 342. Power of Four](questions/342md.md) 30 | * [LeetCode 66. Plus One](questions/66md.md) 31 | * [LeetCode 172. Factorial Trailing Zeroes](questions/172md.md) 32 | * [LeetCode 9. Palindrome Number](questions/9md.md) 33 | * [LeetCode 7. Reverse Integer](questions/7md.md) 34 | * [LeetCode 223. Rectangle Area](questions/223md.md) 35 | * [LeetCode 204. Count Primes](questions/204md.md) 36 | * [LeetCode 168. Excel Sheet Column Title](questions/168md.md) 37 | * 陣列Array 38 | * [LeetCode 283. Move Zeroes](questions/283md.md) 39 | * [LeetCode 349. Intersection of Two Arrays](questions/349md.md) 40 | * [LeetCode 169. Majority Element](questions/169md.md) 41 | * [LeetCode 217. Contains Duplicate](questions/217md.md) 42 | * [LeetCode 350. Intersection of Two Arrays II](questions/350md.md) 43 | * [LeetCode 27. Remove Element](questions/27md.md) 44 | * [LeetCode 118. Pascal's Triangle](questions/118md.md) 45 | * [LeetCode 26. Remove Duplicates from Sorted Array](questions/26md.md) 46 | * [LeetCode 119. Pascal's Triangle II](questions/119md.md) 47 | * [LeetCode 88. Merge Sorted Array](questions/88md.md) 48 | * [LeetCode 219. Contains Duplicate II](questions/219md.md) 49 | * [LeetCode 1. Two Sum](questions/1md.md) 50 | * [LeetCode 189. Rotate Array](questions/189md.md) 51 | * 二元樹Binary Tree 52 | * [LeetCode 104. Maximum Depth of Binary Tree](questions/104md.md) 53 | * [LeetCode 226. Invert Binary Tree](questions/226md.md) 54 | * [LeetCode 100. Same Tree](questions/100md.md) 55 | * [LeetCode 235. Lowest Common Ancestor of a Binary Search](questions/235md.md) 56 | * [LeetCode 102. Binary Tree Level Order Traversal](questions/102md.md) 57 | * [LeetCode 107. Binary Tree Level Order Traversal II](questions/107md.md) 58 | * [LeetCode 101. Symmetric Tree](questions/101md.md) 59 | * [LeetCode 110. Balanced Binary Tree](questions/110md.md) 60 | * [LeetCode 112. Path Sum](questions/112md.md) 61 | * [LeetCode 111. Minimum Depth of Binary Tree](questions/111md.md) 62 | * [LeetCode 257. Binary Tree Paths](questions/257md.md) 63 | * 連結串列LinkedList 64 | * [LeetCode 206. Reverse Linked List](questions/206md.md) 65 | * [LeetCode 237. Delete Node in a Linked List](questions/237md.md) 66 | * [LeetCode 83. Remove Duplicates from Sorted List](questions/83md.md) 67 | * [LeetCode 141. Linked List Cycle](questions/141md.md) 68 | * [LeetCode 21. Merge Two Sorted Lists](questions/21md.md) 69 | * [LeetCode 24. Swap Nodes in Pairs](questions/24md.md) 70 | * [LeetCode 160. Intersection of Two Linked Lists](questions/160md.md) 71 | * [LeetCode 19. Remove Nth Node From End of List](questions/19md.md) 72 | * [LeetCode 234. Palindrome Linked List](questions/234md.md) 73 | * [LeetCode 203. Remove Linked List Elements](questions/203md.md) 74 | * [LeetCode 2. Add Two Numbers](questions/2md.md) 75 | * 動態歸劃Optimization 76 | * [LeetCode 292. Nim Game](questions/292md.md) 77 | * [LeetCode 70. Climbing Stairs](questions/70md.md) 78 | * [LeetCode 121. Best Time to Buy and Sell Stock](questions/121md.md) 79 | * [LeetCode 198. House Robber](questions/198md.md) 80 | * [LeetCode 374. Guess Number Higher or Lower](questions/374md.md) 81 | * [LeetCode 278. First Bad Version](questions/278md.md) 82 | * 其他Others 83 | * [LeetCode 371. Sum of Two Integers](questions/371md.md) 84 | * [LeetCode 191. Number of 1 Bits](questions/191md.md) 85 | * [LeetCode 232. Implement Queue using Stacks](questions/232md.md) 86 | * [LeetCode 36. Valid Sudoku](questions/36md.md) 87 | * [LeetCode 299. Bulls and Cows](questions/299md.md) 88 | * [LeetCode 225. Implement Stack using Queues](questions/225md.md) 89 | * [LeetCode 190. Reverse Bits](questions/190md.md) 90 | * [LeetCode 303. Range Sum Query - Immutable](questions/303md.md) 91 | * [LeetCode 155. Min Stack](questions/155md.md) -------------------------------------------------------------------------------- /book.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "catalog" 4 | ], 5 | "pluginsConfig": {} 6 | } -------------------------------------------------------------------------------- /license.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyyen999/leetcodeWithJS/6b81e02561753b85de3b00ca5a760fe4e104955c/license.png -------------------------------------------------------------------------------- /others.md: -------------------------------------------------------------------------------- 1 | # 其他Others 2 | 3 | -------------------------------------------------------------------------------- /picture/223.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyyen999/leetcodeWithJS/6b81e02561753b85de3b00ca5a760fe4e104955c/picture/223.png -------------------------------------------------------------------------------- /picture/237.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyyen999/leetcodeWithJS/6b81e02561753b85de3b00ca5a760fe4e104955c/picture/237.png -------------------------------------------------------------------------------- /picture/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyyen999/leetcodeWithJS/6b81e02561753b85de3b00ca5a760fe4e104955c/picture/24.png -------------------------------------------------------------------------------- /picture/36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyyen999/leetcodeWithJS/6b81e02561753b85de3b00ca5a760fe4e104955c/picture/36.png -------------------------------------------------------------------------------- /picture/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyyen999/leetcodeWithJS/6b81e02561753b85de3b00ca5a760fe4e104955c/picture/README.md -------------------------------------------------------------------------------- /questions/0md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 7. Reverse Integer 2 | 3 | ##題目 4 | 5 | 6 | ##翻譯 7 | 8 | 9 | ##思路 10 | 11 | ##解題 12 | ``` 13 | 14 | ``` 15 | -------------------------------------------------------------------------------- /questions/100md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 100. Same Tree 2 | 3 | 4 | ##題目 5 | Given two binary trees, write a function to check if they are equal or not. 6 | 7 | Two binary trees are considered equal if they are structurally identical and the nodes have the same value. 8 | ##翻譯 9 | 給定兩個二元樹,判斷這兩個樹的每一個節點中的值與節點位置是否都相同 10 | 11 | ##思路 12 | 這題跟[LeetCode 226. Invert Binary Tree](226md.md)很像,用遞迴解會比迴圈容易理解很多。 13 | 14 | 比較兩個節點的值(val),如果val不同或是子節點數量不相同,都是false,子節點不同就是說其中一邊有左右節點,另外一邊就只有一個左節點或右節點這種情況。 15 | 當目前val與子節點數量都相同,再比較子節點是否相同,將子節點丟入判斷是否相同的function,直到比較完毎個節點都是一樣的,結果才會是true。 16 | 17 | ##解題 18 | ``` 19 | /** 20 | * Definition for a binary tree node. 21 | * function TreeNode(val) { 22 | * this.val = val; 23 | * this.left = this.right = null; 24 | * } 25 | */ 26 | /** 27 | * @param {TreeNode} p 28 | * @param {TreeNode} q 29 | * @return {boolean} 30 | */ 31 | var isSameTree = function(p, q) { 32 | // 如果兩個node都是null,代表所有node比較都是一樣的 33 | if(p === null && q=== null){ 34 | return true; 35 | } 36 | 37 | // one null, other is not null, false 38 | if(p !== null && q=== null || p === null && q !== null){ 39 | return false; 40 | } 41 | 42 | // val diff, false 43 | if(p.val != q.val){ 44 | return false; 45 | } 46 | // find next level of tree 47 | return isSameTree(p.right,q.right)&&isSameTree(p.left, q.left); 48 | }; 49 | 50 | ``` 51 | 52 | 以treeA[1,2,0,3,4,null,5]與treeB[1,2,0,3,4,5,5]兩個二元樹為例 53 | * treeA與treeB第一個節點的val均為1,也都有兩個子節點,進行子節點的比較 54 | * 比較treeA 下一層的左節點2與 treeB 下一層的左節點2,兩者val相同 55 | * 再向下比較,會發現treeA,treeB在左節點下的[3,4]也都是相同的 56 | * 接著比較treeA 下一層的右節點0與 treeB 下一層的右節點0 57 | * treeA節點0下一層的左節點為null,右節點為5,treeB節點0下一層的左節點則是5 58 | * 以上可以判斷這兩個tree是不相等的 59 | 60 | -------------------------------------------------------------------------------- /questions/101md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 101. Symmetric Tree 2 | 3 | ##題目 4 | Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). 5 | 6 | For example, this binary tree [1,2,2,3,4,4,3] is symmetric: 7 | But the following [1,2,2,null,3,null,3] is not: 8 | ##翻譯 9 | 給一個二元樹,判斷他是不是鏡像樹(從root為中心,左邊跟右邊為鏡像)。 10 | 11 | 範例: 12 | [1,2,2,3,4,4,3]是鏡像樹 13 |
14 | 1 15 | / \ 16 | 2 2 17 | / \ / \ 18 | 3 4 4 3 19 |20 | 21 | [1,2,2,null,3,null,3]就不是鏡像樹 22 |
23 | 1 24 | / \ 25 | 2 2 26 | \ \ 27 | 3 3 28 |29 | 30 | ##思路 31 | 判斷右邊是不是左邊的鏡像,就是先把右邊的樹反轉,再判斷是否與左邊的樹相等。 32 | 剛好怎麼把樹反轉在[Invert Binary Tree](questions/226md.md)有寫過,[Same Tree](questions/100md.md)也寫過,把這兩個組合起來就是本題的解了 33 | 34 | ##解題 35 | ``` 36 | /** 37 | * Definition for a binary tree node. 38 | * function TreeNode(val) { 39 | * this.val = val; 40 | * this.left = this.right = null; 41 | * } 42 | */ 43 | /** 44 | * @param {TreeNode} root 45 | * @return {boolean} 46 | */ 47 | var isSymmetric = function(root) { 48 | if(root == null || (root.right == null && root.left == null) ){ 49 | return true; 50 | } 51 | 52 | // 先將right反轉,再比對是否相等 53 | root.right = revertTree(root.right); 54 | return isSameTree(root.left,root.right); 55 | 56 | // 反轉樹 57 | function revertTree(node){ 58 | if(node == null || node.left == null && node.right == null){ 59 | return node; 60 | } 61 | var temp = revertTree(node.left); 62 | node.left = revertTree(node.right); 63 | node.right = temp; 64 | return node; 65 | } 66 | 67 | 68 | // 比對是否相等 69 | function isSameTree(left,right){ 70 | if(left == null && right== null){ 71 | return true; 72 | } 73 | 74 | if(left == null && right != null || right == null &&left != null){ 75 | return false; 76 | } 77 | 78 | if(left.val != right.val){ 79 | return false; 80 | } 81 | 82 | return isSameTree(left.right, right.right) && isSameTree(left.left, right.left) 83 | } 84 | }; 85 | 86 | ``` 87 | 88 | 89 | -------------------------------------------------------------------------------- /questions/102md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 102. Binary Tree Level Order Traversal 2 | 3 | ##題目 4 | Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). 5 | 6 | For example: 7 | Given binary tree [3,9,20,null,null,15,7], 8 | 9 | ##翻譯 10 | 給一個二元樹,每一個階層從左到右裝成一個列陣,再依序放到一個大的列陣裡面。 11 |
12 | 範例: 13 | [3,9,20,null,null,15,7] 14 | 3 15 | / \ 16 | 9 20 17 | / \ 18 | 15 17 19 | 回傳 20 | [ 21 | [3], 22 | [9,20], 23 | [15,7] 24 | ] 25 |26 | 27 | ##思路 28 | [107. Binary Tree Level Order Traversal II](107md.md) 跟這題幾乎一樣,只是107要求的是下面階層的清單放在上面。這邊我們改用迴圈來解,步驟如下: 29 | 1. 用一個map來存放當前節點node的深度level與值val 30 | 2. 將node放到一個watinglist陣列裡面,一開始level為0 31 | 3. 取出watinglist內的node,如果map裡面已經有該level的陣列,增加到裡面,如果沒有,新增map[level]的新陣列 32 | 4. 如果node有子節點,level+1後放入watinglist裡面等處理 33 | 5. 處理watinglist下一個node值到沒有任何元素放在watinglist中 34 | 35 | ##解題 36 | 37 | ``` 38 | /** 39 | * Definition for a binary tree node. 40 | * function TreeNode(val) { 41 | * this.val = val; 42 | * this.left = this.right = null; 43 | * } 44 | */ 45 | /** 46 | * @param {TreeNode} root 47 | * @return {number[][]} 48 | */ 49 | 50 | 51 | var levelOrder = function(root) { 52 | if(root === null || root.length === 0){ 53 | return []; 54 | } 55 | 56 | // 使用map[level]的list儲存相同level節點的值 57 | var map = {}; 58 | 59 | // 待處理節點的等待陣列,第一個要處理的當然就是root 60 | var waitlist = [ { level:0, node:root} ]; 61 | 62 | // 處理到沒有待處理 63 | while(waitlist.length > 0){ 64 | 65 | // 取出waitlist最後一個node來處理 66 | var cur = waitlist.pop(); 67 | var node = cur.node; 68 | 69 | // 如果當前node沒有其他同level的node,產生一個該level的list來裝 70 | if(!map[cur.level]){ 71 | map[cur.level] = [node.val]; 72 | } else { 73 | map[cur.level].push(node.val); 74 | } 75 | 76 | // 有子節點放入待處理清單,注意right要先放,因為上面是抓最後一個放入的節點處理,left後放才會被先處理 77 | if(node.right){ 78 | waitlist.push({level:cur.level+1, node:node.right}); 79 | } 80 | 81 | if(node.left){ 82 | waitlist.push({level:cur.level+1, node:node.left}); 83 | } 84 | 85 | } 86 | var result = []; 87 | 88 | for(var i in map){ 89 | result.push(map[i]); 90 | } 91 | 92 | return result; 93 | }; 94 | 95 | ``` 96 | 97 | 以上面的 [3,9,20,null,null,15,7]來看 98 | 1. 第一次執行時會將整個(node -> level:0,val:3)放入waitlist 99 | 2. 迴圈開始,抓出level:0,val:3的節點,發現map[0]沒有東西,因此map[0] = [3] 100 | 3. [3]的right[20],level+1後放入waitlist,left[9]level+1後放入waitlist 101 | 4. 迴圈,取出最後放入的節點[9],map[1] = [9],[9]沒有子節點 102 | 5. 迴圈,取出剩下的[20],map[1] = [9,20],waitlist放入right[7], left[15] 103 | 6. 接下來迴圈繼續處理[15],[7] 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /questions/104md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 104. Maximum Depth of Binary Tree 2 | 3 | ##題目 4 | Given a binary tree, find its maximum depth. 5 | 6 | The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 7 | 8 | ##翻譯 9 | 找出一個二元樹的深度。 10 | 11 | 範例: 12 |
13 | Tree1 depth = 3 Tree2 depth = 4 14 | A 3 15 | / \ / \ 16 | B C 4 4 17 | / \ / 18 | D E 2 19 | / 20 | 3 21 |22 | ##思路 23 | 這邊用遞迴求解,節點如果left或right有值,則level+1,並判斷left或right有沒有子節點,直到底層,轉換成公式如下: 24 |
25 | fn(n) = 0, if null; 26 | fn(n) = 1 + max(f(n.left), f(n.right)) 27 | 28 | 29 | 以上面tree1為例 30 | *nodeA的深度 = 1 + max (nodeB深度 , nodeC深度) // B,C取深度較深的 31 | *nodeB 沒有子節點,nodeB depth = 1 32 | *nodeC 有子節點[D,E],nodeB depth = 2 33 | *nodeA depth = 1 + 2 = 3 34 | 35 |36 | 37 | 38 | ##解題 39 | ``` 40 | var maxDepth = function(root) { 41 | return find(root); 42 | // 遞迴函式 43 | function find(node){ 44 | // 節點到底 45 | if(node === null){ 46 | return 0; 47 | } 48 | 49 | var deepL = 1; 50 | var deepR = 1; 51 | // 有左節點,往下一層找 52 | if(node.left !== null){ 53 | deepL += find(node.left) 54 | } 55 | // 有右節點,往下一層找 56 | if(node.right !== null){ 57 | deepR += find(node.right) 58 | } 59 | 60 | // 回傳較大的深度depth,給上一層節點 61 | return deepL > deepR ? deepL: deepR; 62 | } 63 | }; 64 | 65 | ``` 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /questions/107md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 107. Binary Tree Level Order Traversal II 2 | 3 | ##題目 4 | Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). 5 | 6 | For example: 7 | Given binary tree [3,9,20,null,null,15,7], 8 | 9 | ##翻譯 10 | 給一個二元樹,每一個階層從左到右裝成一個list,再從下到上放到一個大list裡面。 11 | 12 | 範例: 13 | [3,9,20,null,null,15,7] 14 |
15 | 3 16 | / \ 17 | 9 20 18 | / \ 19 | 15 17 20 | 21 | 回傳 22 | 23 | [ 24 | [15,7], 25 | [9,20], 26 | [3] 27 | ] 28 |29 | 30 | ##思路 31 | 1. 可以先去寫[102. Binary Tree Level Order Traversal](102md.md)這題,兩題是一樣的,這題要再把102題最後的陣列反轉。這邊我們不用迴圈,改用遞迴來寫。 32 | 2. 先處理level 0 的root,將root做為第一個節點傳入遞迴function,當節點沒有left也沒有right的時候,停止遞迴。 33 | 3. 根據傳入的level,如果map裡面已經有該level的list,增加到裡面,如果沒有,map[level] = [node.val]。 34 | 4. 如果當前節點有子節點,先處理left,再處理right。 35 | 5. 不斷的重複3,4步驟值到沒有子節點。 36 | ##解題 37 | 38 | ``` 39 | /** 40 | * Definition for a binary tree node. 41 | * function TreeNode(val) { 42 | * this.val = val; 43 | * this.left = this.right = null; 44 | * } 45 | */ 46 | /** 47 | * @param {TreeNode} root 48 | * @return {number[][]} 49 | */ 50 | var levelOrderBottom = function(root) { 51 | if(root == null) return []; 52 | var result = []; 53 | 54 | // 使用map[level]的list儲存相同level節點的值 55 | var map = {}; 56 | 57 | // 傳入root,level 0 58 | find(root,0); 59 | 60 | for(var i in map){ 61 | result.push(map[i]) 62 | } 63 | return result.reverse(); 64 | 65 | // 傳入node與level 66 | function find(node,level){ 67 | if(node == null) return; 68 | // map[level]沒東西,map[level] = [node.val] 69 | if(!map[level]){ 70 | map[level] = [node.val]; 71 | } else { 72 | map[level].push(node.val); 73 | } 74 | 75 | // 先處理left,再處理right 76 | find(node.left,level+1); 77 | find(node.right,level+1); 78 | } 79 | 80 | 81 | }; 82 | 83 | ``` 84 | -------------------------------------------------------------------------------- /questions/110md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 110. Balanced Binary Tree 2 | ##題目 3 | Given a binary tree, determine if it is height-balanced. 4 | 5 | For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1. 6 | ##翻譯 7 | 給一個二元樹,判斷這是不是一個高度平衡的樹。 8 | 9 | 在這個問題中,高度平衡樹的定義是一個樹兩個子樹每個node的level不能差超過1。 10 | 11 | 範例: 12 |
13 | 高度平衡樹 14 | 1 15 | / \ 16 | 2 5 17 | / \ \ 18 | 3 4 6 19 |20 | 21 |
22 | 在節點5的時候,節點5左子樹level = 1,右子樹level = 3, 3-1 > 1 因此這是非高度平衡樹 23 | 1 24 | / \ 25 | 2 5 26 | / \ \ 27 | 3 4 6 28 | \ 29 | 7 30 |31 | 32 | ##思路 33 | 1. 這題會用到之前寫過的[LeetCode 104. Maximum Depth of Binary Tree](questions/104md.md) 34 | 2. 尋找node左樹的深度與右樹的深樹後相減,如果差超過1,表示非高度平衡樹 35 | 3. 如果沒差超過1,傳入左節點與右節點繼續判斷是否為高度平衡樹 36 | 37 | ##解題 38 | ``` 39 | /** 40 | * Definition for a binary tree node. 41 | * function TreeNode(val) { 42 | * this.val = val; 43 | * this.left = this.right = null; 44 | * } 45 | */ 46 | /** 47 | * @param {TreeNode} root 48 | * @return {boolean} 49 | */ 50 | var isBalanced = function(root) { 51 | if(root == null || (root.right == null && root.left == null)) return true; 52 | 53 | // 找出左樹,右樹的深度 54 | var dL = findDeep(root.left); 55 | var dR = findDeep(root.right); 56 | 57 | // 深度是否差1內 58 | var diff = Math.abs(dL-dR) <= 1; 59 | 60 | //如果深度差超過1, return false 61 | //深度沒差超過1,傳入左右節點繼續判斷 62 | return diff && isBalanced(root.left) && isBalanced(root.right); 63 | 64 | }; 65 | 66 | // 找出節點深度 67 | function findDeep(root){ 68 | if(root == null) { 69 | return 0; 70 | } 71 | var deepL = 1+findDeep(root.left); 72 | var deepR = 1+findDeep(root.right); 73 | 74 | return deepL > deepR ? deepL:deepR; 75 | } 76 | ``` 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /questions/111md .md: -------------------------------------------------------------------------------- 1 | # LeetCode 111. Minimum Depth of Binary Tree 2 | ##題目 3 | Given a binary tree, find its minimum depth. 4 | 5 | The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. 6 | 7 | ##翻譯 8 | 給一個二元樹,找出這棵樹的最小深度。 9 | 10 | 最小深度的定義為,在每一條從root到left的路徑中,最短路徑的深度。 11 | 12 | 範例: 13 |
14 | 1 15 | / \ 16 | 2 5 17 | / \ 18 | 4 6 19 | \ 20 | 7 21 |22 | 上面的二元樹共有三條路徑 23 | [1,2],[1,5,4],[1,5,6,7],最短的當然是深度為2的[1,2] 24 | 25 | ##思路 26 | 1. [104 Maximum Depth of Binary Tree](104md.md)這題已經寫過找root到leaf的深度,拿這個來修改 27 | 2. 使用遞迴來尋找每條路徑的深度(root -> leaf) 28 | 3. 當發現目前這個路徑的深度比min還小,使用目前路徑深度取代min 29 | 30 | ##解題 31 | ``` 32 | /** 33 | * Definition for a binary tree node. 34 | * function TreeNode(val) { 35 | * this.val = val; 36 | * this.left = this.right = null; 37 | * } 38 | */ 39 | /** 40 | * @param {TreeNode} root 41 | * @return {number} 42 | */ 43 | var minDepth = function(root) { 44 | if(root == null) return 0; 45 | if(root.left == null && root.right == null) return 1; 46 | 47 | // 使用min來儲存目前發現的最小路徑 48 | var min = Number.MAX_SAFE_INTEGER; 49 | // root深度為1 50 | findDeep(root,1); 51 | 52 | return min; 53 | 54 | // 用來找路徑深度的function 55 | function findDeep(node,deep){ 56 | // 處理有左節點卻沒右節點,有右沒左這種情況 57 | if(node == null){ 58 | return; 59 | } 60 | 61 | // 沒有子節點,表示這是leaf,終止recursive 62 | if(node.left == null && node.right == null){ 63 | // 判斷從root到目前這個left的路徑是否比目前的min還小 64 | min = deep < min ? deep:min; 65 | return; 66 | } 67 | 68 | findDeep(node.left,deep+1); // 往下找左節點深度 69 | findDeep(node.right,deep+1); // 往下找右節點深度 70 | } 71 | }; 72 | ``` 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /questions/112md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 112. Path Sum 2 | ##題目 3 | Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. 4 | 5 | For example: 6 | Given the below binary tree and sum = 22, 7 |
8 | 5 9 | / \ 10 | 4 8 11 | / / \ 12 | 11 13 4 13 | / \ \ 14 | 7 2 1 15 |16 | return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22. 17 | 18 | ##翻譯 19 | 給一個二元樹與另外一個數字sum,判斷二元樹從根加到葉是否有一個路徑可以得到一個與sum相同的數字。 20 | 21 | 範例: 22 | 例如上面的樹,sum = 22,可以找到 5 + 4 + 11 + 2 = 22,因此return true。 23 | 24 | ##思路 25 | 1. 使用遞迴來加總每一條路徑的總和,其實就是[LeetCode 104. Maximum Depth of Binary Tree](104md.md)的變形,在104中計算的每條路徑的深度,這邊改成計算每個條路徑的總和 26 | 2. 以上面範例的樹為例,一開始root[5],總和s = 0,先計算左節點[4],這時候s=9 27 | 3. [4]沒有右節點,因此只要繼續計算左節點[11],s = 9 + 11 =20 28 | 4. [11]左邊為[7],s = 27 , 因為[7]已經是left,所以比對 s == sum , 不相等就計算下一條路徑 29 | 5. [5,4,11,7]這個路徑不符合,退回[5,4,11],計算[11]的右節點[2],s = 22,等於sum,因此return true。 30 | 31 | 32 | 33 | ##解題 34 | `````` 35 | /** 36 | * Definition for a binary tree node. 37 | * function TreeNode(val) { 38 | * this.val = val; 39 | * this.left = this.right = null; 40 | * } 41 | */ 42 | /** 43 | * @param {TreeNode} root 44 | * @param {number} sum 45 | * @return {boolean} 46 | */ 47 | var hasPathSum = function(root, sum) { 48 | if(root == null) return false; 49 | 50 | // 如果不太清楚怎麼運作,這邊用一個list來儲存每一條root計算後的加總 51 | // 接開下面三行程式與function sumR2L() 裡面 list.push(s)這行單純是為了看清楚每一條root -> leaf的加總,移除掉不會影響程式執行 52 | // 測試資料填 [5,4,8,11,null,13,4], 1 ,可以看到加總為[20,16,17] 53 | var list = []; 54 | sumR2L(root,0); 55 | console.log(list) 56 | 57 | // 起點為root,這時候總和s=0 58 | return sumR2L(root,0); 59 | 60 | // 遞迴function,計算到目前節點的總和,到leaf的時候停下並且判斷是否與傳入的sum相等 61 | function sumR2L(root,s){ 62 | // 到底的時候,判斷總和是否與sum相同 63 | if(root.left == null && root.right == null){ 64 | list.push(s); //將root -> leaft 的加總放到list,測試用 65 | 66 | s += root.val; 67 | return s == sum; 68 | } 69 | 70 | // 左邊還沒到底,右邊已經到底,繼續計算左樹的總和 71 | if(root.left != null && root.right == null){ 72 | return sumR2L(root.left, s+root.val); 73 | } 74 | // 右邊還沒到底,左邊已經到底,繼續計算右邊的總和 75 | if(root.right != null && root.left == null){ 76 | return sumR2L(root.right, s+root.val); 77 | } 78 | 79 | // 兩邊的樹都還沒到底,繼續分別計算總和,因為只要有一條路徑成立就是true,因此使用 or來判斷 80 | return sumR2L(root.left, s+root.val)||sumR2L(root.right, s+root.val); 81 | } 82 | }; 83 | ``` 84 | -------------------------------------------------------------------------------- /questions/118md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 118. Pascal's Triangle 2 | 3 | ##題目 4 | Given numRows, generate the first numRows of Pascal's triangle. 5 | 6 | For example, given numRows = 5, 7 | Return 8 |
9 | [ 10 | [1], 11 | [1,1], 12 | [1,2,1], 13 | [1,3,3,1], 14 | [1,4,6,4,1] 15 | ] 16 |17 | ##翻譯 18 | numRows為列數,產生一個Pascal三角形,例如說 numRows = 5 ,產生三角形如上所示。 19 | 20 | ##思路 21 | 1. 每一列第一個值都是1。 22 | 2. 每一列第n個值則是上一列n-1位子+n位子的值。 23 | 3. 假如是該列最後一個值Nx,前一列沒有Nx這個值,可以視為0。 24 | 4. 有了以上規則,要算出毎一列的值就很簡單了,直接看下面程式碼。 25 | 26 | ##解題 27 | ``` 28 | /** 29 | * @param {number} numRows 30 | * @return {number[][]} 31 | */ 32 | var generate = function(numRows) { 33 | if(numRows == 0) return []; 34 | 35 | // 放入第一列 36 | var trigle = [[1]]; 37 | 38 | for(var i = 1 ; i < numRows ; i++){ 39 | var prevRow = trigle[i-1]; // 前一列 40 | var curRow = [1]; // 每一列開始都是1 41 | 42 | for(var j = 1 ; j <= i; j++){ 43 | // 每一列的第n個值都是 前一列pre[n-1] + pre[n] 44 | var pre = prevRow[j-1]; 45 | var cur = prevRow[j] ? prevRow[j] : 0; 46 | curRow.push(pre+cur); 47 | } 48 | trigle.push(curRow); 49 | } 50 | 51 | return trigle; 52 | }; 53 | ``` 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /questions/119md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 119. Pascal's Triangle II 2 | 3 | ##題目 4 | Given an index k, return the kth row of the Pascal's triangle. 5 | 6 | For example, given k = 3, 7 | Return [1,3,3,1]. 8 | 9 | Note: 10 | Could you optimize your algorithm to use only O(k) extra space? 11 | 12 | ##翻譯 13 | 給一個指標k,回傳第k階的Pascal's三角形。 14 | 15 | 範例: 16 | k=3,回傳[1,3,3,1]。 17 | 18 | 注意:你能改善演算法只用O(k)的額外空間嗎? 19 | 20 | ##思路 21 | 不考慮只使用O(k)額外空間的情況下,只要參考[LeetCode 118. Pascal's Triangle](questions/118md.md)這題,就很簡單。 22 | 23 | 但上面的很像會超出時間,還是要用同一個陣列不斷改變裡面值的方式來做才行。毎一階的Pascal's三角形都可以重上一階算出, 24 | 25 | 計算方法,毎一階開頭一定是1,接下來位子n的數子為上一階陣列pAry[n-1] + pAry[n] 26 | 27 |
28 | * ex. k = 4 29 | * 第一階 array = [1] 30 | * 第二階 array = [1,1] 31 | * 第三階 array = [1,2,1] 32 | * 第四階 array = [1,3,3,1] 33 |34 | 35 | 36 | ##解題 37 | ``` 38 | /** 39 | * @param {number} x 40 | * @return {boolean} 41 | */ 42 | var isPalindrome = function(x) { 43 | /** 44 | * @param {number} rowIndex 45 | * @return {number[]} 46 | */ 47 | var getRow = function(rowIndex) { 48 | if(rowIndex == 0) return [1]; 49 | if(rowIndex == 1) return [1,1]; 50 | 51 | var ary = [1]; 52 | 53 | for(var i = 1 ; i <= rowIndex ; i++){ 54 | // 儲存 ary[n-1]的數字 55 | var prev = ary[i-1]; 56 | for(var j = 1 ; j < i ; j++ ){ 57 | // preVrow[n]的數字,如果preVrow沒有n,設為0 58 | var cur = ary[j] ? ary[j] : 0; 59 | 60 | // 目前row[n]的值為 "上一個prevRow[n-1] + prevRow[n]" 61 | ary[j] = prev + cur; 62 | 63 | prev = cur; 64 | } 65 | ary.push(1); 66 | } 67 | return ary; 68 | }; 69 | ``` 70 | -------------------------------------------------------------------------------- /questions/121md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 121. Best Time to Buy and Sell Stock 2 | 3 | ##題目 4 | Say you have an array for which the ith element is the price of a given stock on day i. 5 | 6 | If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit. 7 | 8 | Example 1: 9 | Input: [7, 1, 5, 3, 6, 4] 10 | Output: 5 11 | 12 | max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price) 13 | 14 | Example 2: 15 | Input: [7, 6, 4, 3, 1] 16 | Output: 0 17 | 18 | In this case, no transaction is done, i.e. max profit = 0. 19 | ##翻譯 20 | 有一個陣列儲存i個數字,這些元素代表一天當中股票的價格。如果在一天中只能做一次交易(買一次然後賣一次),設計一個演算法求得最大獲利。 21 | 22 | 範例1: 23 | Input : [7, 1, 5, 3, 6, 4] 24 | Output: 5 25 | 26 | 最大獲利為6-1=5,因為賣出價格必須比購入價格高,所以7-1是不可行的。 27 | 28 | 範例2: 29 | Input: [7, 6, 4, 3, 1] 30 | Output: 0 31 | 32 | 因為你不管今天怎麼買,賣掉都是虧錢,所以只能回傳0。 33 | 34 | ##思路 35 | 36 | 1. 單一元素最大獲利 = 目前價錢 - 前面出現的最低價格 37 | 2. 跑迴圈計算每個元素可能出現的最大獲利是多少 38 | 3. 如果現在這個元素能的獲利比之前的最大獲利還大,取現在元素的獲利為最大獲利 39 | 40 | ##解題 41 | ``` 42 | /** 43 | * @param {number[]} prices 44 | * @return {number} 45 | */ 46 | var maxProfit = function(prices) { 47 | // min代表目前股票出現的最低價,一開始用MAX_SAFE_INTEGER表示無限大 48 | var min = Number.MAX_SAFE_INTEGER; 49 | 50 | // 目前獲利 51 | var profit = 0; 52 | 53 | for(var i = 0; i < prices.length ; i++){ 54 | // 找出最低點買進 55 | if(prices[i] < min){ 56 | min = prices[i]; 57 | } 58 | 59 | // 計算現在的價錢可以獲利多少 60 | var calProfit = prices[i] - min; 61 | // 現在的價錢賣出是否可以獲得更高的獲利 62 | if(calProfit > profit ){ 63 | profit = calProfit; 64 | } 65 | } 66 | return profit; 67 | }; 68 | ``` 69 | -------------------------------------------------------------------------------- /questions/125md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 125. Valid Palindrome 2 | 3 | ##題目 4 | Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. 5 | 6 | For example, 7 | "A man, a plan, a canal: Panama" is a palindrome. 8 | "race a car" is not a palindrome. 9 | 10 | Note: 11 | Have you consider that the string might be empty? This is a good question to ask during an interview. 12 | 13 | For the purpose of this problem, we define empty string as valid palindrome. 14 | 15 | ##翻譯 16 | 給一個字串,不考慮大小寫與非字母數字的情況下,判斷這個字串是不是迴文。 17 | 18 | 範例: 19 | "A man, a plan, a canal: Panama" --> true 20 | "race a car" --> false (raceacar != racaecar) 21 | 22 | 注意: 23 | 你有考慮過空字串的情況嗎,在這邊我們定義空字串是一個迴文。 24 | 25 | ##思路 26 | 這題我覺得頗簡單,不知道為啥通過率這麼低。 27 | 1. 首先把字串轉為全小寫 28 | 2. 將字串裡面不是字母與數字的部分去除 29 | 3. 反轉字串判斷與上一個步驟處理過的字串相等 30 | 31 | ##解題 32 | ``` 33 | /** 34 | * @param {string} s 35 | * @return {boolean} 36 | */ 37 | var isPalindrome = function(s) { 38 | //轉小寫 39 | s = s.toLowerCase(); 40 | //取代非文字部分 41 | s = s.replace(/[^a-z0-9]/ig,""); 42 | //反轉 43 | var rev = s.split("").reverse().join(""); 44 | //判斷反轉後是否與之前處理過的字串相等 45 | return s.indexOf(rev) == 0; 46 | }; 47 | ``` 48 | -------------------------------------------------------------------------------- /questions/13md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 13. Roman to Integer 2 | 3 | ##題目 4 | Given a roman numeral, convert it to an integer. 5 | 6 | Input is guaranteed to be within the range from 1 to 3999. 7 | 8 | ##翻譯 9 | 給一個羅馬數字符號,將之轉為整數,這個數字一定落在1 到 3999 之間。 10 | 11 | 範例: 12 | I = 1, IX = 9 13 | 14 | ##思路 15 | 使用一個map來儲存羅馬符號跟數字之間的對應關係,在一般的情況下(ex. III, VI),可以直接將羅馬符號轉換成數字。 16 | 17 | 不過如果出現IV,XC這種組合,就要另外處理,這種組合的特色是後面的符號會大於前面的符號,因此一次讀兩個羅馬符號來找出這種組合。 18 | 一次讀兩個羅馬數字,如果第二個數字(n2)比第一個(n1)大,整數值為n2-n1,如果是一般的情況n2 <= n1,整數值為n2+n1。 19 | 20 | ##解題 21 | ``` 22 | /** 23 | * @param {string} s 24 | * @return {number} 25 | */ 26 | var romanToInt = function(s) { 27 | var map = { 28 | I:1, 29 | V:5, 30 | X:10, 31 | L:50, 32 | C:100, 33 | D:500, 34 | M:1000, 35 | } 36 | 37 | var sum = 0; 38 | for(var i = 0 ; i < s.length ; i++){ 39 | var v1 = map[s[i]]; 40 | var v2 = map[s[i+1]]; 41 | if(v2 > v1){ 42 | sum = sum + v2 - v1; 43 | i++; 44 | } else { 45 | sum = sum+v1; 46 | } 47 | } 48 | return sum; 49 | }; 50 | 51 | ``` -------------------------------------------------------------------------------- /questions/141md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 141. Linked List Cycle 2 | 3 | ##題目 4 | Given a linked list, determine if it has a cycle in it. 5 | 6 | Follow up: 7 | Can you solve it without using extra space? 8 | 9 | ##翻譯 10 | 給一個連結陣列,判斷裡面是不是包含一個循環連結。 11 | 12 | 進階: 13 | 你能不使用額外的空間來解這題嗎? 14 | 15 | 範例: 16 | * [1,2,3,2,3,2.....],[1]的next是[2] 17 | * [2]的next是[3] 18 | * [3]的next是[2],從上一步我們知道2的next是[3],所以這是一個循環連結 19 | 20 | 假如[1,2,3,2,3],那就不是一個連結陣列迴圈,因為最後的[3]next並不是[2],所以循環連結不成立。 21 | 22 | ##思路 23 | 拜訪節點後就給他一個拜訪過的標計,如果目前拜訪的節點已經被標計了,代表這是一個循環連結。 24 | 25 | ##解題 26 | ``` 27 | /** 28 | * Definition for singly-linked list. 29 | * function ListNode(val) { 30 | * this.val = val; 31 | * this.next = null; 32 | * } 33 | */ 34 | /** 35 | * @param {ListNode} head 36 | * @return {boolean} 37 | */ 38 | var hasCycle = function(head) { 39 | if(head == null || head.next == null){ 40 | return false; 41 | } 42 | var node = head; 43 | while(node != null ){ 44 | if(node.flag){ 45 | return true; 46 | } 47 | // 標記這個node已經跑過 48 | node.flag = true; 49 | node = node.next; 50 | } 51 | return false; 52 | ``` 53 | 54 | #進階 55 | * 使用快慢指針這個想法來解 56 | * 慢指針一次只跑一格,快指針一次跑兩格 57 | * 如果是一個循環連結,快慢指針一定會相遇 58 | 59 | ``` 60 | /** 61 | * @param {ListNode} head 62 | * @return {boolean} 63 | */ 64 | var hasCycle = function(head) { 65 | if(head == null || head.next == null){ 66 | return false; 67 | } 68 | 69 | var slow = head.next; 70 | var fast = head.next.next; 71 | if(fast == null){ 72 | return false; 73 | } 74 | 75 | while(slow != fast){ 76 | if(fast.next == null){ 77 | return false; 78 | } 79 | slow = slow.next; 80 | fast = fast.next.next; 81 | 82 | if(slow == null || fast == null){ 83 | return false; 84 | } 85 | } 86 | return true; 87 | } 88 | ``` -------------------------------------------------------------------------------- /questions/14md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 14. Longest Common Prefix 2 | 3 | ##題目 4 | Write a function to find the longest common prefix string amongst an array of strings. 5 | 6 | ##翻譯 7 | 一個陣列中有許多個字串,寫一個function找出這些字串最長的共同字首。 8 | 9 | 範例: 10 | ['abcd','abccc','abdec'] --> 共同字首為 'ab' 。 11 | 12 | ##思路 13 | 1. 比對前兩個字串,從頭開始取出相同的部分為共同字首 14 | 2. 後面的字串只要與目前的共同字首比對即可 15 | 3. ['abcd','abccc','abdec'] ,一開始'abcd','abccc'共同字首前3碼'abc' 16 | 4. 接下來只要將'abc','abdec'做比對,發現剩下'ab',也就是最長的共同字首 17 | 18 | ##解題 19 | ``` 20 | /** 21 | * @param {string[]} strs 22 | * @return {string} 23 | */ 24 | var longestCommonPrefix = function(strs) { 25 | if(strs == null || strs.length == 0) return ""; 26 | 27 | // same表示目前發現的共同字首,一開始為strs[0] 28 | var same = strs[0]; 29 | 30 | // 只需要比對same跟目前字串共同的字元就好 31 | for(var i = 1 ; i
8 | A: a1 → a2 9 | ↘ 10 | c1 → c2 → c3 11 | ↗ 12 | B: b1 → b2 → b3 13 |14 | begin to intersect at node c1. 15 | 16 | 17 | ######Notes: 18 | * If the two linked lists have no intersection at all, return null. 19 | * The linked lists must retain their original structure after the function returns. 20 | * You may assume there are no cycles anywhere in the entire linked structure. 21 | * Your code should preferably run in O(n) time and use only O(1) memory. 22 | 23 | ##翻譯 24 | 寫一支程式找出兩個連結陣列的第一個交集的節點。 25 | 26 | ######注意: 27 | * 如果兩個連結陣列沒有交集,回傳null 28 | * 連結陣列必須保持他們的原始結構 29 | * 可以假設不會出現迴圈連結陣列 30 | * 程式只能在O(n)的時間跑完而且只能使用O(1)的空間 31 | 32 | ##思路 33 | 先判斷A跟B哪個連結陣列長度比較長,接著移除較長那邊前面的節點,接下來就兩兩節點比較是否相等。 34 | 35 | ##解題 36 | ``` 37 | /** 38 | * Definition for singly-linked list. 39 | * function ListNode(val) { 40 | * this.val = val; 41 | * this.next = null; 42 | * } 43 | */ 44 | 45 | /** 46 | * @param {ListNode} headA 47 | * @param {ListNode} headB 48 | * @return {ListNode} 49 | */ 50 | var getIntersectionNode = function(headA, headB) { 51 | // 判斷headA, headB 哪個比較長 52 | var diff = getDiff(headA, headB); 53 | 54 | // headA比較長,跳過前面多出的部分 55 | if(diff > 0){ 56 | while(diff > 0){ 57 | headA = headA.next; 58 | diff--; 59 | } 60 | } else { 61 | // headB比較長,跳過前面多出的部分 62 | while(diff < 0){ 63 | headB = headB.next; 64 | diff++; 65 | } 66 | } 67 | 68 | // 毎個節點進行比較 69 | while(headA !=null){ 70 | if(headA == headB){ 71 | return headA; 72 | } 73 | headA = headA.next; 74 | headB = headB.next; 75 | } 76 | 77 | return null; 78 | 79 | 80 | // 取得兩個linked list長度差異 81 | function getDiff(nodeA,nodeB){ 82 | var aLength = 0; 83 | var bLength = 0; 84 | 85 | while(nodeA != null ){ 86 | aLength++; 87 | nodeA = nodeA.next; 88 | } 89 | while(nodeB != null ){ 90 | bLength++; 91 | nodeB = nodeB.next; 92 | } 93 | 94 | return aLength - bLength; 95 | } 96 | }; 97 | ``` 98 | -------------------------------------------------------------------------------- /questions/165md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 165. Compare Version Numbers 2 | 3 | ##題目 4 | Compare two version numbers version1 and version2. 5 | If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0. 6 | 7 | You may assume that the version strings are non-empty and contain only digits and the . character. 8 | The . character does not represent a decimal point and is used to separate number sequences. 9 | For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision. 10 | 11 | Here is an example of version numbers ordering: 12 |
13 | 0.1 < 1.1 < 1.2 < 13.37 14 |15 | 16 | ##翻譯 17 | 比較兩個版本號,version1與version2,如果version1 > version2 回傳1,如果version2 > version1 回傳-1,相等的話回傳0。 18 | 19 | 你可以假設版本號裡面只有數字跟".","."在這邊不是表示小數點而是用來分割子版本的序號。 20 | 舉例來說,2.5不是數字2+0.5,而是第2.5版。 21 | 22 | 下面是一些範例 23 |
24 | 0.1 < 1.1 < 1.2 < 13.37 25 |26 | 27 | ##思路 28 | 版本號是用數字與"."組成,因此先將版號用"."分開放在陣列中,接著就可以跑迴圈比對,如果相同位置下, 29 | version1數字比version2大就表示 version1 > version2,如果到迴圈結束都比不出大小,兩個版號相等。 30 | 31 | 其實這題也可以用純字串來解,速度會快很多,不過因為寫這題的時候我才剛接觸leetcode沒多久,覺得用陣列解會比較清楚。 32 | 33 | ##解題 34 | ``` 35 | /** 36 | * @param {string} version1 37 | * @param {string} version2 38 | * @return {number} 39 | */ 40 | var compareVersion = function(version1, version2) { 41 | // 將版本號用小數點切開 42 | var array1 = version1.split("."); 43 | var array2 = version2.split("."); 44 | 45 | // 取版本號較長的跑loop 46 | var max = array1.length > array2.length ? array1.length:array2.length ; 47 | 48 | for(var i = 0 ; i < max ; i++ ){ 49 | var i1 = parseInt(array1[i]); 50 | var i2 = parseInt(array2[i]); 51 | 52 | // 如果其中一邊後面已經沒版本號,後面就設為0 53 | // ex. [1.0.1], [1.0] 轉換成 [1.0.1], [1.0.0]作比對 54 | i1 = array1.length < i+1 ? 0 : i1; 55 | i2 = array2.length < i+1 ? 0 : i2; 56 | 57 | 58 | // 如果相同位置的版號數字不一樣,就可以判斷哪個版號大 59 | // ex. 1.1.5 < 1.2.2,因為在第二個位置時 2>1 就可以得到答案 60 | if(i1 > i2){ 61 | return 1; 62 | } 63 | if(i2 > i1){ 64 | return -1; 65 | } 66 | } 67 | return 0; 68 | }; 69 | ``` 70 | -------------------------------------------------------------------------------- /questions/168md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 168. Excel Sheet Column Title 2 | 3 | ##題目 4 | Given a positive integer, return its corresponding column title as appear in an Excel sheet. 5 |
6 | For example: 7 | 8 | 1 -> A 9 | 2 -> B 10 | 3 -> C 11 | ... 12 | 26 -> Z 13 | 27 -> AA 14 | 28 -> AB 15 |16 | 17 | ##翻譯 18 | 給一個正整數,回傳在excel表格中對應的欄位。 19 | 20 | ##思路 21 | [下表的來源](https://discuss.leetcode.com/topic/6245/python-solution-with-explanation) 22 |
23 | A 1 AA 26+ 1 BA 2×26+ 1 ... ZA 26×26+ 1 AAA 1×26²+1×26+ 1 24 | B 2 AB 26+ 2 BB 2×26+ 2 ... ZB 26×26+ 2 AAB 1×26²+1×26+ 2 25 | . . .. ..... .. ....... ... .. ........ ... ............. 26 | . . .. ..... .. ....... ... .. ........ ... ............. 27 | . . .. ..... .. ....... ... .. ........ ... ............. 28 | Z 26 AZ 26+26 BZ 2×26+26 ... ZZ 26×26+26 AAZ 1×26²+1×26+26 29 |30 | 31 | 觀察上面表格可以知道數字轉換成excel欄位是一個類似27進位的轉換,不過規則有一點點不同。 32 | 33 | ABC = 1x26^2 + 2x26^1 + 3 ,看起來可以用 String.fromCharCode(n%26 + 64)直接將數字轉成英文字母 34 | ZZZ =26x26^2 + 26x26^1 + 26,可是當n=26,也就是字母Z的時候,26%26 = 0,反而不能得到正確的字母Z 35 | 因此改用***String.fromCharCode((n-1)%26 + 65)***處理 36 | 37 | 38 | ##解題 39 | ``` 40 | /** 41 | * @param {number} n 42 | * @return {string} 43 | */ 44 | var convertToTitle = function(n) { 45 | // String.fromCharCode(65) = 'A', String.fromCharCode(66) = 'B' ..... String.fromCharCode(90) = 'Z' 46 | 47 | // 比27小的時候,可以直接用String.fromCharCode(n)轉換成英文字母 48 | if(n-1 < 26){ 49 | return String.fromCharCode(65+(n-1)%26); 50 | } 51 | 52 | var result = ""; 53 | 54 | while(n > 0){ 55 | var codeNum = (n-1)%26; 56 | var c = String.fromCharCode(codeNum+65); 57 | result = c + result; 58 | 59 | n = parseInt((n-1) / 26); 60 | } 61 | return result; 62 | }; 63 | ``` 64 | 65 | 66 | ##亂湊出來的解法 67 | ``` 68 | /** 69 | * @param {number} n 70 | * @return {string} 71 | */ 72 | var convertToTitle = function(n) { 73 | // String.fromCharCode(65) = 'A', String.fromCharCode(66) = 'B' ..... String.fromCharCode(90) = 'Z' 74 | // 比27小的時候,可以直接用String.fromCharCode(n)轉換成英文字母 75 | if(n < 27){ 76 | return String.fromCharCode(64+n%27); 77 | } 78 | 79 | var result = ""; 80 | 81 | while(n > 0){ 82 | var c = "" 83 | 84 | if(n%26 == 0) { 85 | // n=26時候代表的字母應該為'Z',不過n%26 = 0,因此直接用n%26+64不會得到Z 86 | c = String.fromCharCode(90); 87 | n = parseInt(n/26)-1; 88 | } else { 89 | // 'A' = charCode(1+64),剩下的字母一樣推算 90 | c = String.fromCharCode(n%26+64); 91 | n = parseInt(n/26); 92 | } 93 | result = c + result; 94 | } 95 | return result; 96 | }; 97 | ``` 98 | -------------------------------------------------------------------------------- /questions/169md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 169. Majority Element 2 | 3 | ##題目 4 | Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. 5 | 6 | You may assume that the array is non-empty and the majority element always exist in the array. 7 | 8 | ##翻譯 9 | 長度為n的陣列,找出一個出現n/2次以上的主要元素,假設陣列不會是空值,而且總是會有主要元素存在陣列中。 10 | 11 | ##思路 12 | 用一個map來記錄毎一個元素出現幾次,只要有一個元素出現n/2次,這個元素就是主要元素。 13 | 14 | ##解題 15 | ``` 16 | /** 17 | * @param {number[]} nums 18 | * @return {number} 19 | */ 20 | var majorityElement = function(nums) { 21 | var map = {}; 22 | if(nums.length ===1) {return nums[0]} 23 | 24 | for(var i = 0 ; i < nums.length ; i++){ 25 | // 第一次出現的元素,放到map not in map, push element and set count = 1 26 | if(!map[nums[i]]) { 27 | map[nums[i]] = 1; 28 | } else { 29 | // 出現過的元素,數量增加 element exist, count++ 30 | map[nums[i]]++; 31 | // 判斷這個元素出現的次數 > n/2 32 | if(map[nums[i]] >= nums.length/2){ 33 | return nums[i]; 34 | } 35 | } 36 | } 37 | }; 38 | ``` 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /questions/171md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 171. Excel Sheet Column Number 2 | 3 | ##題目 4 | Related to question Excel Sheet Column Title 5 | 6 | Given a column title as appear in an Excel sheet, return its corresponding column number. 7 | 8 | For example: 9 | 10 | A -> 1 11 | B -> 2 12 | C -> 3 13 | ... 14 | Z -> 26 15 | AA -> 27 16 | AB -> 28 17 | ##翻譯 18 | 將Excel欄位轉換成數字。 19 | 20 | ##思路 21 | 1. A-Z總共26個字母,因此這就是一個26進位的系統 22 | 2. 將字串分別取出字元A-Z,根據[ANSI CODE](http://www.alanwood.net/demos/ansi.html),A的code為65,A = 65 - 64 = 1 23 | 3. 以AB為例, AB = (A)*26^1 + (B)26^0 = 1*26+ 2*1 = 28 24 | 4. 以AZ為例, AZ = (A)*26^1 + (Z)26^0 = 1*26+ 26*1 = 52 25 | 26 | ##解題 27 | ``` 28 | /** 29 | * @param {string} s 30 | * @return {number} 31 | */ 32 | var titleToNumber = function(s) { 33 | var sum = 0; 34 | var exp = 0; 35 | for(var i = s.length -1 ; i >= 0 ; i--){ 36 | // 根據ansi將字元轉成數字,這邊是從字串後面,也就是低位數開始取 37 | var v = s.charCodeAt(i) - 64; 38 | // 毎多一個字元代表26的n次方 39 | v = v*Math.pow(26,exp++); 40 | sum += v; 41 | } 42 | return sum; 43 | }; 44 | ``` -------------------------------------------------------------------------------- /questions/172md.md: -------------------------------------------------------------------------------- 1 | # LeetCodee 172. Factorial Trailing Zeroes 2 | 3 | ##題目 4 | Given an integer n, return the number of trailing zeroes in n!. 5 | 6 | Note: Your solution should be in logarithmic time complexity. 7 | ##翻譯 8 | 給一個正整數n,回傳n!中有幾個0 9 | 10 | 注意:你的解法應該是log(n)的時間複雜度。 11 | 12 | 範例: 13 | n = 5 ; n! = 120 回傳 1。 14 | 15 | ##思路 16 | 1. 當出現0,也就是10的n次方,可以推論一定要出現因子裡面含有2跟5的數字 17 | 2. 2這個數字到處撿都是,真正決定會出現幾個0的,是n!裡面包含幾個5 18 | 3. 例如上面的n=5,5*4*3*2*1 = 120,可以發現5*2 =10,因此會出現一個0 19 | 4. n = 25,會出現 25,20,15,10,5共5個帶有5的數字,不過25其實包含了5*5,所以25!總共會出現5+1=6個10。 20 | 21 | ##解題 22 | ``` 23 | /** 24 | * @param {number} n 25 | * @return {number} 26 | */ 27 | var trailingZeroes = function(n) { 28 | if(n < 5) return 0 ; 29 | 30 | var count = 0; 31 | // 算階層內有幾個5出現 32 | while(n >= 5){ 33 | count += Math.floor(n/5); 34 | n = parseInt(n/5); 35 | } 36 | 37 | return count; 38 | }; 39 | ``` 40 | -------------------------------------------------------------------------------- /questions/189md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 189. Rotate Array 2 | 3 | ##題目 4 | Rotate an array of n elements to the right by k steps. 5 | 6 | For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4]. 7 | 8 | Note: 9 | Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. 10 | 11 | ##翻譯 12 | 給一個n值,n代表陣列中包含1~n個元素與一個整數k,將陣列裡面的元素向右旋轉k次。 13 | 14 | 範例: 15 |
16 | n=7,k=3, array[1,2,3,4,5,6,7] --> [5,6,7,1,2,3,4] 17 |18 | 19 | ##思路 20 | 如果一個陣列的長度為n,向右旋轉k次,其實就跟沒旋轉一樣,所以實際上要旋轉的次數step = n%k。 21 | 22 | 向右旋轉1次,就是將陣列最後面的元素搬到最前面,使用javascript array的pop()可以取出最後一個元素, 23 | unshift(x)可以將元素插到陣列的最前面,這解法太簡單了,因此我們這邊不用這兩個方法來解題。 24 | 25 | 這邊我們用一個暫存陣列temp儲存向右旋轉的元素,需要旋轉k次temp裡面就有幾個元素。題目要求只能在一開始的nums陣列內操作 26 | ,所以接下來就是把nums內沒被旋轉的元素搬到nums的後面,接著將temp放到nums前面。 27 | 28 | 29 | ##解題 30 | ``` 31 | /** 32 | * @param {number[]} nums 33 | * @param {number} k 34 | * @return {void} Do not return anything, modify nums in-place instead. 35 | */ 36 | var rotate = function(nums, k) { 37 | // ex. [1,2,3] k=5 與 [1,2,3] k=2 相同 38 | var step = k%nums.length; 39 | var temp = []; 40 | 41 | // 將向右旋轉的元素裝到temp, [1,2,3] k=2, temp = [2,3] 42 | for(var i = step - 1 ; i >= 0 ; i--) { 43 | var index = nums.length-1-i; 44 | temp.push(nums[index]); 45 | } 46 | 47 | for(var j = nums.length - 1; j >= 0 ; j--){ 48 | if( j >= step){ 49 | // 將nums內沒被旋轉的元素往後移k格,[1,2,3] -> [x,x,1] 50 | nums[j] = nums[j-step]; 51 | } else { 52 | // 將temp放到nums的前面 [2,3,1] 53 | nums[j] = temp[j]; 54 | } 55 | } 56 | 57 | }; 58 | ``` 59 | 60 | ##用javascript強大的array method解題 61 | ``` 62 | var rotate = function(nums, k) { 63 | var step = k%nums.length; 64 | for(var i = 0 ; i < step ; i++){ 65 | var value = nums.pop(); 66 | nums.unshift(value); 67 | } 68 | } 69 | ``` 70 | -------------------------------------------------------------------------------- /questions/190md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 190. Reverse Bits 2 | 3 | ##題目 4 | Reverse bits of a given 32 bits unsigned integer. 5 | 6 | For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000). 7 | 8 | Follow up: 9 | If this function is called many times, how would you optimize it? 10 | 11 | ##翻譯 12 | 給一個32 bits的int整數,反轉整數的bits。 13 | 14 | 範例: 整數43261596 轉換成bits = 00000010100101000001111010011100,將bit反轉00111001011110000010100101000000再轉成整數964176192回傳 15 | 16 | 進階: 17 | 如果這個function會被呼叫很多次,要怎麼做最佳化? 18 | 19 | ##思路 20 | 用除法將十進位數字轉換成二進位數字,也就是bits,將轉換後的二進位數字反轉,再轉回整數。 21 | 22 | 23 | ##解題 24 | ``` 25 | /** 26 | * @param {number} n - a positive integer 27 | * @return {number} - a positive integer 28 | */ 29 | var reverseBits = function(n) { 30 | if(n == 0) return 0; 31 | // 用一個list將n轉為2進位的bits array 32 | var list = []; 33 | 34 | for(var i = 0 ; i < 32 ; i++){ 35 | if(n > 0){ 36 | // 從低位數開始轉換為2進位,放進list時就已經完成反轉的動作 37 | // ex. 6轉換為2進位為110 ( 6 => 6%2 = 0 , 3%2 = 1 , 1%2 =1 ) 38 | list.push(parseInt(n%2)); 39 | n = parseInt(n/2); 40 | } else { 41 | list.push(0); 42 | } 43 | } 44 | 45 | // 將bits array轉換成整數回傳 46 | return parseInt(list.join(""),2); 47 | }; 48 | ``` 49 | -------------------------------------------------------------------------------- /questions/191md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 191. Number of 1 Bits 2 | 3 | ##題目 4 | Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also known as the Hamming weight). 5 | 6 | For example, the 32-bit integer ’11' has binary representation 00000000000000000000000000001011, so the function should return 3. 7 | 8 | ##翻譯 9 | 給一個整數,找出這個整數有幾個'1',例如11用32-bit表示 '00000000000000000000000000001011',總共有3個1,return 3 10 | 11 | ##思路 12 | 這題不考慮效能的話只要收先將將數字n轉為2進位字串,然後跑迴圈找出有多少1。 13 | 14 | ##解題 15 | ``` 16 | /** 17 | * @param {number} n - a positive integer 18 | * @return {number} 19 | */ 20 | var hammingWeight = function(n) { 21 | var count = 0 ; 22 | 23 | // n轉為二進位 24 | var ary = n.toString(2).split(""); 25 | for(var i in ary){ 26 | if(ary[i] % 2 ==1){ 27 | count++; 28 | } 29 | } 30 | return count; 31 | }; 32 | ``` -------------------------------------------------------------------------------- /questions/198md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 198. House Robber 2 | 3 | ##題目 4 | You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night. 5 | 6 | Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. 7 | 8 | ##翻譯 9 | 你是一個專業的小偷,今天你打算偷遍一整條街的房子,每間房子都一定有錢可以偷。不過有一個問題,就是房子之間有設警報系統,如果你連偷兩間相鄰的房子,警報系統就會引來警察,你就會被抓。 10 | 11 | 這邊會給一個list,裡面每個元素都代表這間房子內可以偷到的錢,你要怎麼安排你的偷竊計畫才能偷到最多的錢而且不會驚動警察。 12 | 13 | 範例: 14 | [2,4,5,3],最多可以偷到 2+5+3 = 10,因為4+5+3 = 12雖然可以拿到比較多錢,但是會被警察抓。 15 | 16 | ##思路 17 | 1. 這題跟[LeetCode 121. Best Time to Buy and Sell Stock](questions/121md.md)很像,我們需要計算每間房子可以偷得多少錢,因此需要一個maxS陣列才儲存偷到目前房子最多可以拿到多少錢。 18 | 2. [m0,m1,m2,m3,....],如果房子只有一間[m0],可以偷到的錢為max = mo 19 | 3. 如果有房子兩棟[m0,m1],那最多可以拿到m0,m1之中較大的錢 max = Max(m0,m1) 20 | 3. 三棟房子的情況[m0,m1,m2],最多拿到 max = Max(m0+m2,m1); 21 | 4. 因此可以得到,目前房子n,可以拿到的錢 22 | max = Max( 現在這棟 + 前前一可以拿到的最大金額 , 前一棟可以拿到的最大金額 ) 23 | 24 | ##解題 25 | ``` 26 | /** 27 | * @param {number[]} nums 28 | * @return {number} 29 | * 30 | * 31 | * 32 | */ 33 | var rob = function(nums) { 34 | var maxS = new Array(); 35 | if(nums.length === 0) return 0; 36 | if(nums.length === 1) return nums[0]; 37 | if(nums.length === 2) return Math.max(nums[1],nums[0]); 38 | 39 | maxS.push(nums[0]); 40 | maxS.push(Math.max(nums[0],nums[1])); 41 | 42 | for(var i = 2 ; i < nums.length ; i++){ 43 | //最大金額 = Max(現在金額+前前一棟最大金額 , 前一棟最大金額) 44 | maxS[i] = Math.max(nums[i] + maxS[i-2] , maxS[i-1]);; 45 | } 46 | return maxS.pop(); 47 | }; 48 | 49 | ``` 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /questions/19md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 7. Reverse Integer 2 | 3 | ##題目 4 | Given a linked list, remove the nth node from the end of list and return its head. 5 | 6 | For example, 7 |
8 | Given linked list: 1->2->3->4->5, and n = 2. 9 | 10 | After removing the second node from the end, the linked list becomes 1->2->3->5. 11 |12 | 13 | ######Note: 14 | Given n will always be valid. 15 | Try to do this in one pass. 16 | 17 | ##翻譯 18 | 給一個連結陣列,移除連結陣列從後面數來第n個節點 19 | 20 | 例如, 21 |
22 | 1->2->3->4->5, n = 2. 23 | 24 | 從後面數2個,移除4後的連結陣列變成 1->2->3->5. 25 |26 | 27 | ######注意: 28 | n不會比連結陣列還長,試著跑一次迴圈解題。 29 | 30 | ##思路 31 | 這題可以用快慢指針的做法,就是快指針先走n個節點,慢指針再開始與快指針一起跑,當快指針到底的時候,慢指針會停在要移除的節點n上面。 32 | 33 | 不過慢指針應該要停在要移除節點的前一點才對,因為連結陣列的刪除,應該是前一點跳過下一點,這樣當前的節點就會被刪除。 34 | 因此將慢指針的起點改在一個假的首節點0上面修正這個問題。 35 | 36 | ##解題 37 | ``` 38 | /** 39 | * Definition for singly-linked list. 40 | * function ListNode(val) { 41 | * this.val = val; 42 | * this.next = null; 43 | * } 44 | */ 45 | /** 46 | * @param {ListNode} head 47 | * @param {number} n 48 | * @return {ListNode} 49 | */ 50 | var removeNthFromEnd = function(head, n) { 51 | if(head == null) return head; 52 | 53 | // 用假節點當首節點,方便操作 54 | var node = new ListNode(0); 55 | node.next = head; 56 | 57 | 58 | var slow = node; 59 | var fast = head; 60 | 61 | // 快指針先跑n個節點 62 | while(n > 0){ 63 | fast = fast.next; 64 | n--; 65 | } 66 | 67 | // 因為快指針已經先跑n點,所以當快指針fast跑完,慢指針slow會在要移除的前一點上 68 | while(fast){ 69 | fast = fast.next; 70 | slow = slow.next; 71 | } 72 | if(slow.next == null){ 73 | slow.next = null ; 74 | } else { 75 | slow.next = slow.next.next; 76 | } 77 | 78 | return node.next; 79 | }; 80 | ``` 81 | * [1,2,3,4] , n = 2,fast = [1,2,3,4] , slow = [0,1,2,3,4] (0為假節點) 82 | * n = 2,快指針先走2點,fast = [3,4],slow = [0,1,2,3,4] 83 | * 快慢指針一起跑,當fast = null,slow = [2,3,4],這時候慢指針必須跳過他第2個點,也就是跳過3 -------------------------------------------------------------------------------- /questions/1md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 1. Two Sum 2 | 3 | ##題目 4 | Given an array of integers, return indices of the two numbers such that they add up to a specific target. 5 | 6 | You may assume that each input would have exactly one solution. 7 | 8 | Example: 9 |
10 | Given nums = [2, 7, 11, 15], target = 9, 11 | 12 | Because nums[0] + nums[1] = 2 + 7 = 9, 13 | return [0, 1]. 14 |15 | 16 | ##翻譯 17 | 給一個裡面元素為int的陣列,陣列中會有兩個元素加起來等於target,回傳這兩個元素的位置。 18 | 19 | 範例: 20 | [2, 7, 11, 15], target = 9,2+7=9,因此回傳[1,2] 21 | 22 | ##思路 23 | 相信大部分人跟我一樣,接觸leetCode的時候都是先寫這題,這題完全就是Easy的題目,使用雙迴圈,如果nums[i]+nums[j] = target 就回傳i,j 24 | 25 | ##解題 26 | ``` 27 | /** 28 | * @param {number[]} nums 29 | * @param {number} target 30 | * @return {number[]} 31 | */ 32 | var twoSum = function(nums, target) { 33 | 34 | var map = {}; 35 | for(var i = 0 ; i < nums.length ; i++){ 36 | var v = nums[i]; 37 | 38 | for(var j = i+1 ; j < nums.length ; j++ ){ 39 | if( nums[i] + nums[j] == target ){ 40 | return [i,j]; 41 | } 42 | } 43 | 44 | } 45 | }; 46 | ``` 47 | 48 | #進階 49 | 上面雙迴圈的時間複雜度是O(n^2),效率明顯不太好,用map就可以在一次走訪中找到i,j的位置 50 | ``` 51 | var twoSum = function(nums, target) { 52 | 53 | var map = {}; 54 | for(var i = 0 ; i < nums.length ; i++){ 55 | var v = nums[i]; 56 | 57 | if(map[target-v] >= 0){ 58 | // 如果 target - v可以在map中找到值x,代表之前已經出現過值x, target = x + v 59 | // 因此回傳 x的位置與目前v的位置 60 | return [map[target-v],i] 61 | } else { 62 | // 使用map儲存目前的數字與其位置 63 | 64 | map[v] = i; 65 | } 66 | } 67 | }; 68 | ``` -------------------------------------------------------------------------------- /questions/202md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 202. Happy Number 2 | 3 | Write an algorithm to determine if a number is "happy". 4 | 5 | A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers. 6 | 7 | Example: 19 is a happy number 8 | 1^2 + 9^2 = 82 9 | 8^2 + 2^2 = 68 10 | 6^2 + 8^2 = 100 11 | 1^2 + 0^2 + 0^2 = 1 12 | 13 | ##翻譯 14 | 判斷一個數字是否為happy number。 15 | 16 | happy number 定義如下:當一個數的每位數平方後相加,大於1則重複每位數開平方相加的動作,如果最後得到1的話,這個數就是happy number,如果進入無窮迴圈,這個數就不是happy number。 17 | 18 | ##思路 19 | 使用一個map儲存計算過的數字,如果目前的數字已經計算過,表示無窮迴圈出現,return false。持續計算到1出現true或是無窮迴圈出現false。 20 | 21 | 範例:判斷4是不是happy number 22 |
23 | 4^2 = 16 24 | 1^2 + 6^2 = 37 25 | 3^2 + 7^2 = 58 26 | ..... 27 | ......... = 20 28 | 2^2 + 0 = 4 29 | 4重複出現,因此進入無窮迴圈 30 |31 | 32 | ##解題 33 | ``` 34 | /** 35 | * @param {number} n 36 | * @return {boolean} 37 | */ 38 | var isHappy = function(n) { 39 | // map儲存計算過的數字 40 | var store = {}; 41 | 42 | // 如果map裡面出現過這個數字 或 數字 = 1,停止迴圈。 43 | while(!store[n] && n!=1){ 44 | store[n] = n; 45 | // 單純的計算毎一個位數的平方和 46 | n.toString().split("").forEach(function(v,i){ 47 | if(i == 0) n = 0; 48 | n += v*v; 49 | }) 50 | n = parseInt(n); 51 | } 52 | return n == 1; 53 | }; 54 | ``` 55 | 56 | ##Plus 57 | * 以下這種寫法也可以,1~9之中,只有1,7是happy number 58 | * 如果n超過10,計算到最後一定會落在1~9之中 59 | * 判斷計算到最後的數字是不是1 60 | 61 | ``` 62 | /** 63 | * @param {number} n 64 | * @return {boolean} 65 | */ 66 | var isHappy = function(n) { 67 | while(n>6){ 68 | n.toString().split("").forEach(function(v,i){ 69 | if(i == 0) n = 0; 70 | n += v*v; 71 | }) 72 | } 73 | return n == 1; 74 | }; 75 | ``` 76 | -------------------------------------------------------------------------------- /questions/203md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 203. Remove Linked List Elements 2 | 3 | ##題目 4 | Remove all elements from a linked list of integers that have value val. 5 | 6 | Example 7 | Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6 8 | Return: 1 --> 2 --> 3 --> 4 --> 5 9 | 10 | ##翻譯 11 | 給一個值val,移除連結陣列中所有值為val的節點。 12 | 13 | 14 | ##思路 15 | 1. 走訪連結陣列,只要比對目前節點與val相等,就移除目前這點 16 | 2. 移除一個節點,其實是讓前一個節點跳過目前節點直接指向下一個節點 17 | 3. [1,6,3,5] val=3 ,移除[3],因此我們需要知道[3]的前一點是[6]讓[6].next -> [5] 18 | 19 | ##解題 20 | ``` 21 | /** 22 | * Definition for singly-linked list. 23 | * function ListNode(val) { 24 | * this.val = val; 25 | * this.next = null; 26 | * } 27 | */ 28 | /** 29 | * @param {ListNode} head 30 | * @param {number} val 31 | * @return {ListNode} 32 | */ 33 | var removeElements = function(head, val) { 34 | if(head == null) return null; 35 | 36 | // prev一開始為假節點,例如[2],val=2的時候,就可以讓假節點指向null,完成移除的動作 37 | var node = new ListNode(0); 38 | 39 | // [1,2,3] val=2,當走到[2]的時候,移除目前[2]這點的方法是讓[1]跳過2直接接[3],變成[1,3], 40 | // 所以這邊需要先儲存前一個節點prev來備用 41 | var prev =node; 42 | node.next = head; 43 | 44 | while(head != null){ 45 | if(head.val != val){ 46 | // 目前節點與val不相等,往下一個 47 | prev = head; 48 | head = head.next; 49 | } else { 50 | // 目前節點與val相等,跳過目前節點 51 | prev.next = head.next; 52 | head = head.next; 53 | } 54 | 55 | } 56 | 57 | return node.next; 58 | 59 | }; 60 | ``` 61 | -------------------------------------------------------------------------------- /questions/204md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 204. Count Primes 2 | 3 | ##題目 4 | Description: 5 | 6 | Count the number of prime numbers less than a non-negative number, n. 7 | 8 | ##翻譯 9 | 給一個n,計算比n小的質數有幾個。 10 | 11 | 12 | ##思路 13 | 1. 網路上解質數問題的演算法很多,這邊用比較原始的方法 14 | 2. 判斷n之下有幾個質數,只要跑迴圈判斷從2~(n-1)中毎一個數是不是質數就可以 15 | 3. 質數p的定義就是 p/2 , p/3 , p/4 .... p/(p-1)都不等於0 16 | 4. 實作上不需要除到p-1,只需要除到"p的平方根"就可以,而且可以跳過2的倍數 p/2, p/3 , p/5 , p/7 ..... 17 | 18 | ##解題 19 | ``` 20 | /** 21 | * @param {number} n 22 | * @return {number} 23 | */ 24 | var countPrimes = function(n) { 25 | // n = 3的時候,才會出現第一個比n小的質數2 26 | if(n < 3) return 0; 27 | 28 | var count = 1; 29 | // 加快速度,所以跳過2的倍數 30 | for(var i = 3 ; i < n ; i+=2){ 31 | var flag = true; 32 | // 判斷i是不是質數 33 | for(var j = 3 ; j*j <= i; j+=2){ 34 | if(i%j == 0){ 35 | // i能被比自己小的數除盡,表示i不是質數 36 | flag = false; 37 | break; 38 | } 39 | } 40 | 41 | if(flag) count++; 42 | } 43 | 44 | return count; 45 | }; 46 | 47 | 48 | ``` 49 | -------------------------------------------------------------------------------- /questions/205md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 205. Isomorphic Strings 2 | 3 | ##題目 4 | Given two strings s and t, determine if they are isomorphic. 5 | 6 | Two strings are isomorphic if the characters in s can be replaced to get t. 7 | 8 | All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself. 9 | 10 | For example, 11 | Given "egg", "add", return true. 12 | 13 | Given "foo", "bar", return false. 14 | 15 | Given "paper", "title", return true. 16 | 17 | ##翻譯 18 | 給兩個字串s跟t,判斷他們是否是同構字。 19 | 20 | 如果他們是同構字,表示s裡面毎個字元都可以拿來對應t的特定字元。 21 | 22 | 全部的字元都要依順序被取代,而且s一種字元只會對應t一種字元,也可能對應到與自己相同的字元。 23 | 24 | 25 | ##思路 26 | 需要兩個map,一個記錄s對t的對應關係,另外一個記錄t對s,如果字元沒在s中出現,加到map,出現過的話就拿出來跟t比對,不一致表示非同構字。 27 | 28 | 29 | 30 | ##解題 31 | ``` 32 | /** 33 | * @param {string} s 34 | * @param {string} t 35 | * @return {boolean} 36 | */ 37 | var isIsomorphic = function(s, t) { 38 | // 使用map來記錄s,t的對應關係 39 | var mapS = {}; 40 | var mapT = {}; 41 | 42 | for(var i in s){ 43 | var valueS = s[i]; 44 | var valueT = t[i]; 45 | 46 | // 如果這個字元還沒出現過,加到mapS中 47 | if(!mapS[valueS]){ 48 | mapS[valueS] = valueT; 49 | } else if(mapS[valueS] != valueT) { 50 | // 如果s字元出現過,比對t的字元使否與mapS中儲存的一樣 51 | return false; 52 | } 53 | 54 | if(!mapT[valueT]){ 55 | mapT[valueT] = valueS; 56 | } else if(mapT[valueT] != valueS) { 57 | return false; 58 | } 59 | } 60 | // 全部比對成功 61 | return true; 62 | }; 63 | ``` 64 | -------------------------------------------------------------------------------- /questions/206md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 206. Reverse Linked List 2 | 3 | ##題目 4 | Reverse a singly linked list. 5 | 6 | ##翻譯 7 | 反轉一個連結串列。 8 | 9 | 範例: 10 | { 11 | val:1, 12 | next: {val:2, next:null} 13 | } 14 | } 15 | 16 | 反轉: 17 | { 18 | val:2, 19 | next: {val:1, next:null} 20 | } 21 | } 22 | 23 | ##思路 24 | 反轉一個連結陣列,需要一個指標來操作連結陣列,找出指標前的陣列並且將這個陣列加到目前指標節點的位置,這時候指標向前。 25 | 26 | 例如連結head[3,2,1] 27 | 1. 指標一開始放在[2]的位置,第一步將指標前的[3]從連結中切出來然後加到[2]的後面,連結陣列變成[3,2,1]。 28 | 2. 接下來指標向後移動到[1],切出前面的[2,3]應且加到[1]之後,連結陣列變成[1,2,3] 29 | 3. 指標在往後移,發現後面已經沒有節點,交換完成。 30 | 31 | ##解題 32 | ``` 33 | /** 34 | * Definition for singly-linked list. 35 | * function ListNode(val) { 36 | * this.val = val; 37 | * this.next = null; 38 | * } 39 | */ 40 | /** 41 | * @param {ListNode} head 42 | * @return {ListNode} 43 | */ 44 | var reverseList = function(head) { 45 | if(!head){ 46 | return null; 47 | } 48 | 49 | if(!head.next){ 50 | return head; 51 | } 52 | 53 | var prev = head; 54 | var cur = head.next; 55 | prev.next = null; 56 | 57 | while(cur != null){ 58 | var temp = cur; // 用temp來操作目前的node 59 | cur = cur.next; // 目前的node指標先往下,不然會被後面的操作影養 60 | 61 | // 這邊其實是兩個步驟 62 | // 我們只需要當前node的值,不需要他的next,temp.next = null 63 | // 將之前的linked list加到當前node後面 , temp.next = prev 64 | temp.next = prev; 65 | 66 | // 交換完成的temp變成新的prev 67 | prev = temp; 68 | } 69 | return prev; 70 | }; 71 | ``` 72 |
73 | * 給一個linked list = [1,2,3,4]。 執行while前,prev = head = [1,2,3,4] ; cur = head.next = [2,3,4] 74 | * 來看看prev,我們只需要[1],後面的[2,3,4]都必須移除,prev.next=null,prev = [1] 75 | * 第一次進入while, temp = cur = [2,3,4]。 這時候要讓cur指向[3,4],不然對temp的操作也會影響到cur 76 | * 這邊我們需要只留下[2]而不是[2,3,4],temp.next = null ; temp = [2] 77 | * 將prev接到temp後面,temp.next = prev; temp = [2,1]; cur = [3,4] 78 | * 交換完成,temp變成新的prev,prev = temp, prev = [2,1] 79 | * 重複以上步驟,值到反轉完成。 80 |-------------------------------------------------------------------------------- /questions/20md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 20. Valid Parentheses 2 | 3 | ##題目 4 | Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. 5 | 6 | The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not. 7 | 8 | ##翻譯 9 | 給一個只包含'(', ')', '{', '}', '[' , ']'這些括號字元的字串,判斷這些括號是不是合法的。 10 | 右括號必須依照正確的順序出現,"()" 與 "()[]{}" 都是合法的,但"(]" 和 "([)]"就不是。 11 | 12 | 13 | ##思路 14 | 用stack先進後出的特性來解,遇到左括號就放入stack,遇到右括號就取出stack裡面的左括號比對是否合法。 15 |
16 | 例如說字串 " ( [ ) ] " , '(' 左括號,放入stack -> stack='(', '['放入stack = '([' 17 | ')'右括號,取出stack -> '[' , [)是一個不match的組合,就回傳false 18 |19 | 20 | ##解題 21 | ``` 22 | /** 23 | * @param {string} s 24 | * @return {boolean} 25 | */ 26 | var isValid = function(s) { 27 | if(!s) return true; 28 | 29 | // 使用stack還儲存左括號 30 | var stack = []; 31 | 32 | var left = ['(','[','{']; 33 | var right = [')',']','}']; 34 | var match = { 35 | ')':'(', 36 | ']':'[', 37 | '}':'{' 38 | } 39 | 40 | for(var i in s){ 41 | // 左括號,放入stack 42 | if(left.indexOf(s[i]) > -1){ 43 | stack.push(s[i]); 44 | } 45 | 46 | // 右括號,從stack取出左括號判斷是否match 47 | if(right.indexOf(s[i]) > -1){ 48 | var stackStr = stack.pop(); 49 | if(match[s[i]] != stackStr) { 50 | return false; 51 | } 52 | } 53 | } 54 | 55 | // 如果左右括號都match的話,stack應該為空 56 | return stack.length == 0; 57 | }; 58 | ``` 59 | -------------------------------------------------------------------------------- /questions/217md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 217. Contains Duplicate 2 | 3 | ##題目 4 | Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct. 5 | ##翻譯 6 | 給一個陣列,確認陣列中是否有重複的元素 7 | 8 | ##思路 9 | 解題方向與[169. Majority Element](questions/169md.md)完全相通,使用map,當一個元素count = 2時,回傳true,迴圈如果跑完回傳false。 10 | 11 | ##解題 12 | ``` 13 | /** 14 | * @param {number[]} nums 15 | * @return {boolean} 16 | */ 17 | var containsDuplicate = function(nums) { 18 | var keep = []; 19 | for(var i in nums){ 20 | if(keep.indexOf(nums[i])<0){ 21 | keep.push(nums[i]); 22 | } else { 23 | return true; 24 | } 25 | } 26 | return false; 27 | }; 28 | ``` 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /questions/219md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 219. Contains Duplicate II 2 | 3 | ##題目 4 | Given an array of integers and an integer k, 5 | find out whether there are two distinct indices i and j in the array 6 | such that nums[i] = nums[j] and the difference between i and j is at most k. 7 | 8 | ##翻譯 9 | 給一個陣列nums跟一個整數k,判斷能不能在陣列中找到nums[i] = nums[j](i,j為不同的值),而且i跟j的距離不能比k還大。 10 | 11 | 範例: 12 | nums = [1,2,3,4,1] k=3; nums[0] = nums[4] = 1 , j=4, i=0, i,j距離為4比k還大,因此為false 13 | nums = [1,2,3,4,1] k=4; nums[0] = nums[4] = 1 , j=4, i=0, i,j距離為4沒有比k大,因此為true 14 | 15 | ##思路 16 | 1. 使用一個map存放出現過的數字以及位置 17 | 2. 如果出現重複的數字,判斷目前位置與儲存的位置距離是否小於等於k,有的話直接回傳true 18 | 3. 陣列中沒有符合的配對,回傳false 19 | 20 | ##解題 21 | ``` 22 | /** 23 | * @param {number[]} nums 24 | * @param {number} k 25 | * @return {boolean} 26 | */ 27 | var containsNearbyDuplicate = function(nums, k) { 28 | if(nums.length <= 1) return false; 29 | 30 | // 使用map儲存出現過的數字 31 | var map = {}; 32 | 33 | for(var i in nums){ 34 | var v = nums[i]; 35 | 36 | if(map[v] && (i - map[v] <= k)){ 37 | // 如果有出現重複的數字,判斷目前的位置-之前儲存的位置 <= k,符合條件return true 38 | return true; 39 | } 40 | // 將出現過的數字與其位置放入map 41 | map[v] = i; 42 | } 43 | 44 | // 全部跑完,沒符合條件的配對,return false 45 | return false; 46 | }; 47 | ``` 48 | -------------------------------------------------------------------------------- /questions/21md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 21. Merge Two Sorted Lists 2 | 3 | ##題目 4 | Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. 5 | 6 | ##翻譯 7 | 融合兩個排序過的連結串列為一個新的連結串列後回傳。 8 | 9 | 範例: 10 | [1,2,2,3] + [1,3] = [1,1,2,2,3,3] 11 | 12 | ##思路 13 | 讀取L1目前的值與L2目前的值比較,如果L1.val < L2.val,將當前的L1節點加入新的連結串列(result),然後L1指向下一個節點。 14 | 如果L1.val > L2.val較小,則把L2當前的節點加到result,直到L1或L2一方為null則停止比較,並且將另外一邊剩下的節點加入result。 15 | 16 | ##解題 17 | ``` 18 | /** 19 | * Definition for singly-linked list. 20 | * function ListNode(val) { 21 | * this.val = val; 22 | * this.next = null; 23 | * } 24 | */ 25 | /** 26 | * @param {ListNode} l1 27 | * @param {ListNode} l2 28 | * @return {ListNode} 29 | */ 30 | var mergeTwoLists = function(l1, l2) { 31 | // 儲存結果的ListNode 32 | var result = new ListNode(0); 33 | // 目前Node位置 34 | var c = result; 35 | 36 | while(l1 !== null && l2 !==null){ 37 | // l1,l2較小的數加入result 38 | if(l1.val > l2.val){ 39 | c.next = l2; 40 | l2 = l2.next; 41 | } else { 42 | c.next = l1; 43 | l1 = l1.next 44 | } 45 | c = c.next; 46 | } 47 | 48 | //將l1,l2剩下的Node加到result 49 | if(l1 !== null){ 50 | c.next = l1; 51 | } 52 | 53 | if(l2 !== null){ 54 | c.next = l2; 55 | } 56 | return result.next 57 | }; 58 | ``` -------------------------------------------------------------------------------- /questions/223md.md: -------------------------------------------------------------------------------- 1 | # 223. Rectangle Area 2 | 3 | ##題目 4 | Find the total area covered by two rectilinear rectangles in a 2D plane. 5 | 6 | Each rectangle is defined by its bottom left corner and top right corner as shown in the figure. 7 | 8 |  9 | 10 | Assume that the total area is never beyond the maximum possible value of int. 11 | 12 | ##翻譯 13 | 計算兩個長方形所覆蓋的面積,每個長方形都是由左下頂點與右上頂點決定,如圖所示。 14 | 15 | 假設覆蓋面積不會過int的最大值。 16 | 17 | ##思路 18 | 1. 先考慮兩個長方形不交疊的情況,只要單純的計算面積相加即可 19 | 2. AB,EF分別為左下頂點,CD,GH分別為右上頂點,如果A>=G表示第一個長方形在第二個長方形右側而且面積不重疊 20 | 3. 同樣方法可判斷兩個長方形其他三個點是否有交疊的情況 21 | 4. 如果有交疊的情況發生,使用max(A,E)可以找出交疊正方形的左下頂點,同樣方法可以找出交疊正方形正確位置並計算面積 22 | 23 | ##解題 24 | ``` 25 | /** 26 | * @param {number} A 27 | * @param {number} B 28 | * @param {number} C 29 | * @param {number} D 30 | * @param {number} E 31 | * @param {number} F 32 | * @param {number} G 33 | * @param {number} H 34 | * @return {number} 35 | */ 36 | var computeArea = function(A, B, C, D, E, F, G, H) { 37 | // 分別計算ABCD與EGFH的面積 38 | var r1 = Math.abs(A-C)*Math.abs(B-D); 39 | var r2 = Math.abs(E-G)*Math.abs(F-H); 40 | 41 | // 如果ABCD與EGFH沒重疊,直接將r1,r2加總 42 | if( A >= G || B >= H || C <= E || D <= F){ 43 | return r1+r2; 44 | } 45 | 46 | // 計算重疊的部分 47 | var rD = Math.abs( (Math.max(A,E) - Math.min(C,G)) * (Math.max(B,F) - Math.min(D,H)) ) 48 | 49 | return r1+r2 - rD; 50 | }; 51 | ``` 52 | -------------------------------------------------------------------------------- /questions/225md.md: -------------------------------------------------------------------------------- 1 | # 225. Implement Stack using Queues 2 | 3 | ##題目 4 | Implement the following operations of a stack using queues. 5 | 6 | push(x) -- Push element x onto stack. 7 | pop() -- Removes the element on top of the stack. 8 | top() -- Get the top element. 9 | empty() -- Return whether the stack is empty. 10 | 11 | ######Notes: 12 | You must use only standard operations of a queue -- which means only push to back, peek/pop from front, size, and is empty operations are valid. 13 | Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue. 14 | You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack). 15 | 16 | 17 | ##翻譯 18 | 19 | 使用queue來實做 stack。 20 | 21 | * push(x) -- 將一個元素x放入queue最後面 22 | * pop() -- 移除stack最上面的元素 23 | * peek() -- 取得stack最上面的元素(不刪除) 24 | * empty() -- 檢查stack是否是空的 25 | 26 | 注意: 27 | 你只能用標準的queue方法操作,這表示只有push到queue後端,peek/pop queueu前端的元素,size以及sEmpty這些方法是可以用的。 28 | 29 | 有些語言可能沒有支援queue,你可以使用類似的結構,例如list或deque, 只要你的操作符合上述的標準queue方法。可以假設全部的操作都是合法的(例如說當stack是empty的時候,不會執行pop這樣的操作)。 30 | 31 | 32 | 33 | ##思路 34 | 跟[LeetCode 232. Implement Queue using Stacks](questions/232md.md)幾乎一樣,直接看code就可以。 35 | 36 | ##解題 37 | ``` 38 | /** 39 | * 使用一個自製的簡易queue來實作stack 40 | * @constructor 41 | */ 42 | var Stack = function() { 43 | this.queue = new Queue(); 44 | }; 45 | 46 | 47 | /** 48 | * queue跟stack都是把x加到最後面 49 | * @param {number} x 50 | * @returns {void} 51 | */ 52 | Stack.prototype.push = function(x) { 53 | this.queue.push(x); 54 | }; 55 | 56 | /** 57 | * @returns {void} 58 | */ 59 | Stack.prototype.top = function() { 60 | var element; 61 | var keep = new Queue(); 62 | while(!this.queue.isEmpty()){ 63 | element = this.queue.pop(); 64 | keep.push(element); 65 | } 66 | 67 | while(!keep.isEmpty()){ 68 | this.queue.push(keep.pop()); 69 | } 70 | return element; 71 | }; 72 | 73 | /** 74 | * @returns {number} 75 | */ 76 | Stack.prototype.pop = function() { 77 | var element; 78 | var keep = new Queue(); 79 | while(!this.queue.isEmpty()){ 80 | element = this.queue.pop(); 81 | if(!this.queue.isEmpty()){ 82 | keep.push(element); 83 | } 84 | } 85 | 86 | while(!keep.isEmpty()){ 87 | this.queue.push(keep.pop()); 88 | } 89 | return element; 90 | }; 91 | 92 | /** 93 | * 跟判斷queue是否為空一樣 94 | * @returns {boolean} 95 | */ 96 | Stack.prototype.empty = function() { 97 | return this.queue.isEmpty(); 98 | }; 99 | 100 | 101 | /** 102 | * 用array實做一個簡單的Queue 103 | */ 104 | var Queue = function(){ 105 | this.list = []; 106 | } 107 | 108 | /** 109 | * push跟array的push一樣,加到最後 110 | */ 111 | Queue.prototype.push = function(x){ 112 | this.list.push(x); 113 | } 114 | 115 | /** 116 | * peek回傳第一筆資料但是不刪除 117 | */ 118 | Queue.prototype.peek = function(){ 119 | return this.list[0]; 120 | } 121 | /** 122 | * pop拿出第一筆資料 123 | */ 124 | Queue.prototype.pop = function(){ 125 | return this.list.shift(); 126 | } 127 | /** 128 | * 判斷list裡面是不是沒東西 129 | */ 130 | Queue.prototype.isEmpty = function(){ 131 | return this.list.length == 0; 132 | } 133 | 134 | ``` 135 | -------------------------------------------------------------------------------- /questions/226md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 226. Invert Binary Tree 2 | 3 | ##題目 4 | Invert a binary tree. 5 | 6 | ##翻譯 7 | 反轉一個二元樹。 8 | 9 | 範例: 10 | 輸入 11 |
12 | 4 13 | / \ 14 | 2 7 15 | / \ / \ 16 | 1 3 6 9 17 |18 | 反轉 19 |
20 | 4 21 | / \ 22 | 7 2 23 | / \ / \ 24 | 9 6 3 1 25 |26 | 27 | ##思路 28 | 第一次解這題的時候還跟遞迴不怎麼熟,一直用迴圈嘗試,結果也沒寫出來,那時候心中的不斷的OS,不是說好這是Easy的題目嗎!!!? 29 | 30 | 後來看討論發現用遞迴來解會比較好理解很多,如果你現在心中跟我有一樣的OS,那建議過幾周後再回來重寫一次。 31 | 32 | 反轉整顆樹,其實除了已經到底的節點(left)之外,毎一個節點都需要把他的左右節點互換,例如上面的[4, left:2, right:7],就要把2,7互換, 33 | [2, left:1, right:3],[7, left:6, right:9]也都是一樣,到了底部[1,3,6,9]這幾個點就不用交換,表示遞迴結束。 34 | 35 | ##解題 36 | ``` 37 | /** 38 | * Definition for a binary tree node. 39 | * function TreeNode(val) { 40 | * this.val = val; 41 | * this.left = this.right = null; 42 | * } 43 | */ 44 | /** 45 | * @param {TreeNode} root 46 | * @return {TreeNode} 47 | */ 48 | var invertTree = function(root) { 49 | //節點為null或沒有子節點,不用反轉,終止遞迴 50 | if(root === null || (root.right === null && root.left === null)){ 51 | return root; 52 | } 53 | // 左節點為本來的右節點反轉,右節點為本來的左節點反轉 54 | var temp = root.left; 55 | root.left = invertTree(root.right); 56 | root.right = invertTree(temp); 57 | 58 | return root; 59 | 60 | }; 61 | ``` 62 | 63 |
64 | * 以[4][2,7][1,3,6,9]這個樹來說明 65 | * 執行時傳入節點4,發現有左節點[2],右節點[7],將[2][7]交換 66 | * 交換同時發現新的左節點[7]有子節點[9,6],交換成為[6,9],因為[6][9]都沒子節點,遞迴結束 67 | * 接著看新的右節點[2],有子節點[1,3],步驟同上 68 | * 上述步驟執行後就會得到反轉的tree [4][7,2][9,6,3,1] 69 |-------------------------------------------------------------------------------- /questions/231md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 231. Power of Two 2 | 3 | ##題目 4 | Given an integer, write a function to determine if it is a power of two. 5 | 6 | ##翻譯 7 | 判斷一個整數是否是2的次方數。 8 | 9 | ##思路 10 | 只要n大於3不斷的將輸入值n除2,如果發現餘數不等於0,那他就不是2的次方數。 11 | 12 | ##解題 13 | ``` 14 | /** 15 | * @param {number} n 16 | * @return {boolean} 17 | */ 18 | var isPowerOfTwo = function(n) { 19 | if(n <= 0) return false; 20 | if(n === 1) return true; 21 | while(n>3){ 22 | if(n%2 != 0) return false; 23 | n = parseInt(n/2); 24 | } 25 | return n%2 === 0; 26 | }; 27 | ``` 28 | 29 | #Plus 30 | 例用javascript的特性,稍為改寫一下,增加效能 31 | ``` 32 | /** 33 | * @param {number} n 34 | * @return {boolean} 35 | */ 36 | var isPowerOfTwo = function(n) { 37 | if(n <= 0) return false; 38 | if(n === 1) return true; 39 | while(n>5){ 40 | n = n/2; 41 | } 42 | return n%2 === 0; 43 | }; 44 | ``` -------------------------------------------------------------------------------- /questions/232md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 232. Implement Queue using Stacks 2 | 3 | ##題目 4 | Implement the following operations of a queue using stacks. 5 | 6 | push(x) -- Push element x to the back of queue. 7 | pop() -- Removes the element from in front of queue. 8 | peek() -- Get the front element. 9 | empty() -- Return whether the queue is empty. 10 | Notes: 11 | You must use only standard operations of a stack -- which means only push to top, peek/pop from top, size, and is empty operations are valid. 12 | Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack. 13 | You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue). 14 | ##翻譯 15 | 使用stacks來實做queue。 16 | 17 | * push(x) -- 將一個元素x放入queue最後 18 | * pop() -- 移除queue最前面的元素 19 | * peek() -- 取得queue最前面的元素(不刪除) 20 | * empty() -- 檢查queue是否是空的 21 | 22 | 注意: 23 | 你只能用標準的stack方法操作,這表示只有push到stack頂端, peek/pop stack頂端的元素, size, isEmpty這些方法是可以用的。 24 | 25 | 有些語言可能沒有支援stack,你可以使用類似的結構,例如list或deque, 只要你的操作符合上述的標準stack方法。可以假設全部的操作都是合法的(例如說當queue是empty的時候,不會執行pop這樣的操作)。 26 | 27 | ##思路 28 | 用javascrip來做這題其實頗簡單的,array本身的特定就跟stack差不多 29 | 30 | 1. push --> list.push(x)的特性跟queue一樣,都是把x加到最後面 31 | 2. empty --> 判斷queue是否empty跟判斷stack一樣,都是判斷裡面的array.length是不是0,不過題目限定只能用標準的stack方法,因此我們只能用stack.size() == 0來判斷。 32 | 3. pop --> 這比較麻煩,因為只能用stack.pop()來實做,這邊用一個keep stack來保存stack裡面拿出來的東西,在拿出stack最後一筆資料時再倒回去。 33 | 4. peek --> 跟pop類似,直接看下面程式碼差異的部分就可以 34 | 35 | ##解題 36 | ``` 37 | /** 38 | * @constructor 39 | */ 40 | var Queue = function() { 41 | this.stack = []; 42 | }; 43 | 44 | 45 | // 自己在 array裡面加上stack的size方法 46 | Array.prototype.size = function () { 47 | return this.length; 48 | }; 49 | 50 | 51 | /** 52 | * @param {number} x 53 | * @returns {void} 54 | */ 55 | Queue.prototype.push = function(x) { 56 | this.stack.push(x); 57 | }; 58 | 59 | /** 60 | * queue的pop()是拿出最底下一筆,stack的pop()是拿出最上面一筆 61 | * 因此stack不斷的pop()值到最後一筆才是我們要的資料 62 | * 使用另外一個stack來保存之前拿出的資料,取出之後將keep裡面的資料倒回我們的queue 63 | * @returns {void} 64 | */ 65 | Queue.prototype.pop = function() { 66 | 67 | var keep = []; // 儲存從stack拿出來的資料 68 | var element ; // 要回傳的資料 69 | 70 | // 從stack裡面不斷的倒資料到keep,直到最後一筆 71 | while(this.stack.size() > 1){ 72 | keep.push(this.stack.pop()); 73 | } 74 | 75 | // 最後一筆是我們要回傳的資料,而且他不會回到stack中了 76 | var element = this.stack.pop(); 77 | 78 | // 把keep的資料倒回stack 79 | while(keep.size() > 0){ 80 | this.stack.push(keep.pop()); 81 | } 82 | 83 | return element; 84 | }; 85 | 86 | /** 87 | * @returns {number} 88 | */ 89 | Queue.prototype.peek = function() { 90 | var keep = []; 91 | var element ; 92 | 93 | while(this.stack.size() > 1){ 94 | keep.push(this.stack.pop()); 95 | } 96 | 97 | var element = this.stack.pop(); 98 | 99 | // 跟pop不同的是,最後一筆要回到stack中 100 | keep.push(element); 101 | 102 | while(keep.size() > 0){ 103 | this.stack.push(keep.pop()); 104 | } 105 | return element; 106 | } 107 | 108 | /** 109 | * @returns {boolean} 110 | */ 111 | Queue.prototype.empty = function() { 112 | return this.stack.size() == 0; 113 | }; 114 | ``` 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /questions/234md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 234. Palindrome Linked List 2 | 3 | ##題目 4 | Given a singly linked list, determine if it is a palindrome. 5 | 6 | Follow up: 7 | Could you do it in O(n) time and O(1) space? 8 | 9 | ##翻譯 10 | 給一個單向的連結陣列,判斷他是不是一個回文連結陣列。 11 | 12 | 進階:你能使用O(n)的時間與O(1)的空間來處理這個題目嗎? 13 | 14 | ##思路 15 | 1. 不考慮進階題的情況很簡單,走訪連結陣列,使用兩個字串來處理 16 | 2. 一個正向字串(str = str + value),另外一個為反向字串(str = value+str) 17 | 3. 最後判斷兩個字串是否相等 18 | 19 | ##解題 20 | ``` 21 | /** 22 | * Definition for singly-linked list. 23 | * function ListNode(val) { 24 | * this.val = val; 25 | * this.next = null; 26 | * } 27 | */ 28 | /** 29 | * @param {ListNode} head 30 | * @return {boolean} 31 | */ 32 | var isPalindrome = function(head) { 33 | 34 | var rec = ""; //反向字串 35 | var seq = ""; //正向字串 36 | 37 | while(head != null){ 38 | seq += head.val; 39 | rec = head.val + rec; 40 | head = head.next; 41 | } 42 | // 反向字串與正向字串相等就是回文陣列 43 | return seq == rec; 44 | 45 | }; 46 | ``` 47 | 48 | ##進階 49 | 因為用了另外一個字串,因此額外空間為O(n),不符合進階的要求,為了不使用額外的O(n)空間,我們先用快慢指針找出linked list的中點 50 | ,找到後從中點之後將linked list反轉再與本來的head前半段比較是否相等,這邊需要一個額外的空間儲存反轉後的linked list。 51 | 52 | ``` 53 | var isPalindrome = function(head) { 54 | 55 | var middle = findMiddle(head); // 找尋中點 56 | var rNode = reverseNode(middle); // 從中點反轉 57 | 58 | // 比對反轉後的node與head前半段是否相等 59 | while(rNode != null){ 60 | if(head.val != rNode.val) { 61 | return false; 62 | } 63 | head = head.next; 64 | rNode = rNode.next; 65 | } 66 | return true; 67 | 68 | 69 | 70 | // 使用快慢指針找出中點 71 | function findMiddle(node){ 72 | var fast = node; 73 | var slow = node; 74 | 75 | while(fast != null && fast.next != null){ 76 | slow = slow.next; 77 | fast = fast.next.next; 78 | } 79 | return slow; 80 | } 81 | 82 | // 反轉linked list 83 | function reverseNode(node){ 84 | if(node==null || node.next==null) return node; 85 | var prev = null; 86 | var cur = node; 87 | while(cur != null){ 88 | var temp = cur; 89 | cur = cur.next; 90 | temp.next = prev; 91 | prev = temp; 92 | } 93 | return prev; 94 | } 95 | }; 96 | ``` -------------------------------------------------------------------------------- /questions/235md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 235. Lowest Common Ancestor of a Binary Search 2 | 3 | Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. 4 | 5 | According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” 6 |
7 | _6_ 8 | / \ 9 | 2 8 10 | / \ / \ 11 | 0 4 7 9 12 | / \ 13 | 3 5 14 |15 | For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition. 16 | 17 | ##翻譯 18 | 給一個二元搜尋樹(BST),再給兩個樹中的節點Node,找出這兩個Node的最低共同祖先節點,根據LCA在維基百科的定義: "最低共同祖先節點,是指在一個Tree T中的Node v, Node w存在一個最低層級共同的祖先T,同時 v與w也可以算是自己的祖先節點" 19 | 20 | 範例:以上面的樹來看,[2,8]的最低共同祖先節點為6。 21 | [2,4]的最低共同祖先節點為2,因為2也算是自己的祖先節點 22 | 23 | ##思路 24 | 一個BST,若任意節點的左子樹不為空,則左子樹所有節點的值都會比根節點小,從上面的樹可以看到6的左子樹裡面的節點為[2,0,4,3,5]均比6小。 25 | 26 | 1. 取得根節點root的值,如果值落在目標節點[p,q]之間,代表root就是最低共同祖先節點 27 | 2. 如果root比[p,q]都還小,用root.right取代root繼續往下找 28 | 3. 如果root比[p,q]都還小,用root.left取代root繼續往下找 29 | 30 | ##解題 31 | ``` 32 | /** 33 | * Definition for a binary tree node. 34 | * function TreeNode(val) { 35 | * this.val = val; 36 | * this.left = this.right = null; 37 | * } 38 | */ 39 | /** 40 | * @param {TreeNode} root 41 | * @param {TreeNode} p 42 | * @param {TreeNode} q 43 | * @return {TreeNode} 44 | */ 45 | var lowestCommonAncestor = function(root, p, q) { 46 | var count = 0; 47 | 48 | while(true){ 49 | var value = root.val; 50 | 51 | if(p.val >= value && value >= q.val || p.val <= value && value <= q.val){ 52 | return root; 53 | } else if(p.val > value && q.val > value){ 54 | root = root.right; 55 | } else { 56 | root = root.left; 57 | } 58 | } 59 | }; 60 | ``` 61 | 62 | 63 | -------------------------------------------------------------------------------- /questions/237md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 237. Delete Node in a Linked List 2 | 3 | ##題目 4 | Write a function to delete a node (except the tail) in a singly linked list, given only access to that node. 5 | 6 | Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, 7 | the linked list should become 1 -> 2 -> 4 after calling your function. 8 | 9 | 10 | ##翻譯 11 | 刪除連結串列的一個節點。 12 | 13 | 範例: 14 | 連結陣列1 -> 2 -> 3 -> 4 ,傳入3,則執行後連節陣列變成1 -> 2 -> 4 15 | 16 | ##思路 17 | 連結陣列每個節點(Node)有兩個屬性,值(val)與下一個節點(next),刪除節點其實就是讓連結的val與next。都跳過當前節點指向下一個節點。 18 | 19 | 其實這題沒很好,可以跳過,沒有顯示出連結陣列的特性,[203. Remove Linked List Elements](203md.md)會比較完整的使用到連結陣列的特性。 20 | 21 | 22 | ##解題 23 | ``` 24 | /** 25 | * Definition for singly-linked list. 26 | * function ListNode(val) { 27 | * this.val = val; 28 | * this.next = null; 29 | * } 30 | */ 31 | /** 32 | * @param {ListNode} node 33 | * @return {void} Do not return anything, modify node in-place instead. 34 | */ 35 | var deleteNode = function(node) { 36 | node.val = node.next.val; 37 | node.next = node.next.next; 38 | }; 39 | ``` 40 | 以上程式碼用圖解釋,一開始的連結如上圖,將val:3節點的值用val:4取代,並將node.next指向val:5節點,本來val:4的記憶體空間就會被釋放出來 41 | 42 |  43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /questions/242md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 242. Valid Anagram 2 | ##題目 3 | Given two strings s and t, write a function to determine if t is an anagram of s. 4 | 5 | For example, 6 | s = "anagram", t = "nagaram", return true. 7 | s = "rat", t = "car", return false. 8 | 9 | Note: 10 | You may assume the string contains only lowercase alphabets. 11 | 12 | ##翻譯 13 | 給兩個字串s與t,回傳t是否為s的重組字 14 | 15 | 範例: 16 | s = "anagram", t = "nagaram" 回傳true 17 | s = "rat", t = "car" 回傳false 18 | 19 | ##思路 20 | 要比較兩個字串裡面的字元是否相同,首先可以判斷長度是否相等,不相等就可以直接判定為false, 21 | 接下來將重新排序後的字串比較是否相等。 22 | 23 | ##解題 24 | ``` 25 | /** 26 | * @param {string} s 27 | * @param {string} t 28 | * @return {boolean} 29 | */ 30 | var isAnagram = function(s, t) { 31 | if(s.length != t.length) return false; 32 | 33 | var s = s.split("").sort().join(""); 34 | var t = t.split("").sort().join(""); 35 | 36 | return s == t; 37 | }; 38 | 39 | ``` 40 | -------------------------------------------------------------------------------- /questions/24md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 24. Swap Nodes in Pairs 2 | 3 | ##題目 4 | Given a linked list, swap every two adjacent nodes and return its head. 5 | 6 | For example, 7 | Given 1->2->3->4, you should return the list as 2->1->4->3. 8 | 9 | Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed. 10 | 11 | ##翻譯 12 | 給一個連結陣列,交換兩兩相鄰的節點並且回傳。 13 | 14 | 範例: 15 | 1->2->3->4, return 2->1->4->3。 16 | 17 | 你的演算法不能改變節點裡面的值,只能把節點搬來搬去。 18 | 19 | ##思路一 20 | 先不管最後一條規則,也就是直接改變節點裡面值 21 | 1. 用prev表示前面的節點,cur表示後面的節點,跟一般交換的寫法一樣,先用一個temp儲存prev的值 22 | 2. 將cur的值塞給prev,然後再將temp的值塞給cur就完成交換 23 | 3. prev與cur尋找下一對node,繼續交換到結束 24 | 25 | ##解題 26 | ``` 27 | 改變node內的值 28 | 29 | /** 30 | * Definition for singly-linked list. 31 | * function ListNode(val) { 32 | * this.val = val; 33 | * this.next = null; 34 | * } 35 | */ 36 | /** 37 | * @param {ListNode} head 38 | * @return {ListNode} 39 | */ 40 | var swapPairs = function(head) { 41 | if(head == null || head.next == null) return head; 42 | var prev = head; 43 | var cur = head.next; 44 | 45 | while(prev != null && cur != null){ 46 | // 很一般的交換 47 | var temp = prev.val; 48 | prev.val = cur.val; 49 | cur.val = temp; 50 | 51 | if(cur.next == null || cur.next.next == null) break; 52 | // 處理下一對node 53 | prev = cur.next; 54 | cur = cur.next.next; 55 | } 56 | return head; 57 | }; 58 | 59 | ``` 60 | ##思路二 61 | 1. 題目要求不能改變節點裡面的值,所以node.val這種寫法應該是不行的 62 | 2. 首先先弄一個不動的首節點firstNode,後面節點移來移去時才不會受影響 63 | 3. 以[1,2,3,4],一開始要交換的為[1.2],因此需要先儲存[3,4]稍後再處理(下圖1) 64 | 4. 儲存後將list要處理的部分[1,2]跟不處理的部分[3,4]切開 (下圖2),切開的同時讓[2]的next指向[1] 65 | 5. 將前一個節點prev的next指向[2],因為[2]的next已經指向[1],因此這邊已經完成[1,2] -> [2,1]的步驟 66 | 6. 接下來把之前儲存的[3,4]接到[1]後面,就可以繼續處理[3,4] 67 | ``` 68 | 69 | 不改動node內的值 70 | 71 | var swapPairs = function(head) { 72 | if(head == null || head.next == null) return head; 73 | 74 | var firstNode = new ListNode(0); 75 | 76 | firstNode.next = head; 77 | var cur = head; 78 | var prev = firstNode; 79 | // 圖1的部分,目前處理的節點cur,前一個節點prev 80 | 81 | var nextKeep; // 預備用來儲存後面未處理的節點 82 | 83 | while (cur!=null && cur.next!=null){ 84 | nextKeep = cur.next.next; //圖1,相將後面的節點[3,4]儲存起來 85 | cur.next.next = cur; //圖2,將[1,2]與[3,4]斷開,這時候[2]的next已經變成[1] 86 | // 圖3將prev的next指向[2],注意這時候[2]的next已經指向[1],整理一下其實如圖4 87 | prev.next = cur.next; 88 | 89 | //圖5,將[3,4]接回[1] 90 | cur.next = nextKeep; 91 | 92 | //處理下一組 93 | prev = cur; 94 | cur = cur.next; 95 | } 96 | return firstNode.next; 97 | } 98 | ``` 99 | 100 | ## 圖解不改動node值的寫法 101 | 102 | 103 | 104 |  -------------------------------------------------------------------------------- /questions/255md.md: -------------------------------------------------------------------------------- 1 | # 205. Isomorphic Strings 2 | 3 | ##題目 4 | Given two strings s and t, determine if they are isomorphic. 5 | 6 | Two strings are isomorphic if the characters in s can be replaced to get t. 7 | 8 | All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself. 9 | 10 | For example, 11 | Given "egg", "add", return true. 12 | 13 | Given "foo", "bar", return false. 14 | 15 | Given "paper", "title", return true. 16 | 17 | Note: 18 | You may assume both s and t have the same length. 19 | 20 | ##翻譯 21 | 給s,t兩個字串,判斷他們是否為同構字,同構字的意思是s中的每一個字元在t中都有相對應的字元 22 | 23 | 範例: 24 | "egg", "add", return true. 25 | 26 | "foo", "bar", return false. 27 | 28 | "paper", "title", return true. 29 | 30 | 31 | 你可以假設s,t的長度一樣的 32 | ##思路 33 | 1. 這邊用map來記錄s,t的對應關係 34 | 2. 如果已經在map中有紀錄,比對失敗回傳false 35 | 3. 全部比對成功回傳true 36 | ##解題 37 | ``` 38 | /** 39 | * @param {string} s 40 | * @param {string} t 41 | * @return {boolean} 42 | */ 43 | var isIsomorphic = function(s, t) { 44 | // 使用map來記錄s,t的對應關係 45 | var mapS = {}; 46 | var mapT = {}; 47 | 48 | for(var i in s){ 49 | var valueS = s[i]; 50 | var valueT = t[i]; 51 | 52 | // 如果這個字元還沒出現過,加到mapS中 53 | if(!mapS[valueS]){ 54 | mapS[valueS] = valueT; 55 | } else if(mapS[valueS] != valueT) { 56 | // 如果s字元出現過,比對t的字元使否與mapS中儲存的一樣 57 | return false; 58 | } 59 | 60 | // t對應s也是一樣的方法處理 61 | if(!mapT[valueT]){ 62 | mapT[valueT] = valueS; 63 | } else if(mapT[valueT] != valueS) { 64 | return false; 65 | } 66 | } 67 | // 全部比對成功 68 | return true; 69 | }; 70 | ``` 71 | -------------------------------------------------------------------------------- /questions/257md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 257. Binary Tree Paths 2 | 3 | ##題目 4 | Given a binary tree, return all root-to-leaf paths. 5 | 6 | For example, given the following binary tree: 7 |
8 | 1 9 | / \ 10 | 2 3 11 | \ 12 | 5 13 |14 | All root-to-leaf paths are: 15 | ["1->2->5", "1->3"] 16 | 17 | ##翻譯 18 | 給一個二元樹,回傳全部root到leaf的路徑,例如圖中的二元樹, 19 | 有兩條路徑["1->2->5", "1->3"] 20 | 21 | ##思路 22 | 跟[111. Minimum Depth of Binary Tree](111md.md)差不多,題目111中我們已經能找出每條path的深度, 23 | 這邊改成紀錄路徑,走訪毎一條路徑到達leaf的時候,就把路徑放到陣中。 24 | 25 | ##解題 26 | ``` 27 | /** 28 | * Definition for a binary tree node. 29 | * function TreeNode(val) { 30 | * this.val = val; 31 | * this.left = this.right = null; 32 | * } 33 | */ 34 | /** 35 | * @param {TreeNode} root 36 | * @return {string[]} 37 | */ 38 | var binaryTreePaths = function(root) { 39 | if(!root) return []; 40 | // 使用list儲存每一條path 41 | var list = []; 42 | findPath(root,""); 43 | return list; 44 | 45 | // 走訪每一條path 46 | function findPath(node,str){ 47 | // left, right 都是null,代表已經到了leaf,一條路徑完成 48 | if(node.right == null && node.left == null){ 49 | list.push(str + node.val); // 走完一條路徑放到list 50 | } else { 51 | // 將目前節點的值加到str,並繼續走訪子節點 52 | if(node.left != null) { 53 | findPath(node.left,str + node.val + "->" ); 54 | } 55 | if(node.right != null) { 56 | findPath(node.right,str + node.val + "->" ); 57 | } 58 | } 59 | } 60 | }; 61 | ``` 62 | -------------------------------------------------------------------------------- /questions/258md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 258. Add Digits 2 | ##題目 3 | Given a non-negative integer num, repeatedly add all its digits until the result has only one digit. 4 | 5 | For example: 6 | 7 | Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it. 8 | 9 | Follow up: 10 | Could you do it without any loop/recursion in O(1) runtime? 11 | 12 | ##翻譯 13 | 將一個數字每個位數相加,直到剩個位數為止。 14 | 15 | 範例: 16 | num = 38,則 3+8 = 11,1+1 = 2, 2是個為數,回傳2。 17 | 18 | 進階: 19 | 不用迴圈,遞迴解這個問題 20 | 21 | ##思路 22 | 取出每個位數的值,例如說38 -> [3,8],然後將取出的數字相加,如果大於等於10,重複動作直到數字小於10。 23 | 24 | ##解題 25 | 方法一 26 | ``` 27 | var addDigits = function(num) { 28 | while(num >= 10){ 29 | var n = num; 30 | var sum = 0; 31 | // 取出每個位數的值 32 | // ex. n = 138, 138%10 = 8, sum = 8, n = 13 33 | // n = 13, 13%10 = 3, sum =11, n = 1 34 | while(parseInt(n/10) > 0){ 35 | sum += parseInt(n%10); 36 | n = parseInt(n/10); 37 | } 38 | // sum = 11, n = 1, sum + n%10 = 12, 39 | num = parseInt(n%10) + sum; 40 | } 41 | return num; 42 | }; 43 | 44 | ``` 45 | 方法二 46 | ``` 47 | var addDigits = function(num) { 48 | while(num >= 10){ 49 | var sum = 0; 50 | // 將數字轉成字串並切開放在陣列 ex. 138 => [1,3,8] 51 | (''+num).split('').forEach(function(v){ 52 | sum += parseInt(v); 53 | }); 54 | num = sum; 55 | return num; 56 | }; 57 | 58 | ``` 59 | 60 | 61 | --- 62 | 63 | ##進階 64 | 這已經是偏向數學的範圍,怎麼證明這邊就跳過了,麻煩自己上網搜尋, 65 | 簡單說就是判斷一個數是否為9的倍數,可以從每個位數相加是否能被9整除直接判斷,運用這樣的想法,直接取這個數除9的餘數。 66 | ``` 67 | var addDigits = function(num) { 68 | if(num == 0) return 0; 69 | if(num%9==0) return 9; 70 | return num%9; 71 | }; 72 | ``` 73 | -------------------------------------------------------------------------------- /questions/263md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 263. Ugly Number 2 | 3 | ##題目 4 | Write a program to check whether a given number is an ugly number. 5 | 6 | Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 6, 8 are ugly while 14 is not ugly since it includes another prime factor 7. 7 | 8 | Note that 1 is typically treated as an ugly number. 9 | 10 | ##翻譯 11 | 判斷一個數字是否為ugly number 12 | 13 | ugly number是說一個數字因式分解後只含有2,3,5這些因子,例如說6[2,3],8[2,2,2]都是ugly的,14[2,7]因為含有7,所以不是ugly。 14 | 15 | 注意: 1 是一個ugly number ([LeetCode 202. Happy Number](questions/202md.md)這題可以看到,1也是一個happy number,可知道1是一個醜但是樂觀的數字 XD) 16 | ##思路 17 | 一開始我是想用先排出一個在n之下的質數表,用這個表來因數分解,不過這種寫法會超出時間。 18 | 19 | 重新想了一下,發現單純用除法可以解,一個n如果小於7,一定是ugly number,如果大於等於7,將n裡面的2,3,5因子除掉,最後如果還有剩下其他因子,這個數字就不是ugly number。 20 | 21 | ##解題 22 | ``` 23 | /** 24 | * @param {number} num 25 | * @return {boolean} 26 | */ 27 | var isUgly = function(num) { 28 | if(num <= 0){ 29 | return false; 30 | } 31 | if(num <= 6) return true; 32 | 33 | while(num > 2){ 34 | if(num%2 !== 0){ 35 | break; 36 | } 37 | num = parseInt(num/2); 38 | } 39 | 40 | while(num > 3){ 41 | if(num%3 !== 0){ 42 | break; 43 | } 44 | num = parseInt(num/3); 45 | } 46 | 47 | while(num > 5){ 48 | if(num%5 !== 0){ 49 | break; 50 | } 51 | num = parseInt(num/5); 52 | } 53 | return num%2===0 || num % 3 === 0 || num%5 ===0; 54 | } 55 | ``` 56 | -------------------------------------------------------------------------------- /questions/26md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 26. Remove Duplicates from Sorted Array 2 | 3 | ##題目 4 | Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. 5 | 6 | Do not allocate extra space for another array, you must do this in place with constant memory. 7 | 8 | For example, 9 | Given input array nums = [1,1,2], 10 | 11 | Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length. 12 | 13 | ##翻譯 14 | 給一個排序過的陣列,移除重複的值,每個元素只能留下一個。 15 | 16 | 不能使用其他的陣列空間,必需在本來的陣列中操作。 17 | 18 | 範例: 19 | [1,1,2] 去除重複的1之後,剩下[1,2],回傳陣列的長度2。 20 | 21 | ##思路 22 | 1. 這跟 [LeetCode 283. Move Zeroes](283md.md) 很像,差別在於283移除的是0,這題移除的是重複的數字。 23 | 2. 使用一個count來紀錄有多少不重複的元素。 24 | 3. 當陣列中下一個元素與當前的元素重複,就跳過當前的元素,不重複就放在陣列中。 25 | 26 | ##解題 27 | ``` 28 | /** 29 | * @param {number[]} nums 30 | * @return {number} 31 | */ 32 | var removeDuplicates = function(nums) { 33 | if(nums == null || nums.length == 0) return 0; 34 | if(nums.length == 1) return 1; 35 | var count = 0; 36 | for(var i = 1 ; i < nums.length ; i++){ 37 | if(nums[count] != nums[i]){ 38 | count++; 39 | nums[count] = nums[i]; 40 | } 41 | } 42 | return ++count; 43 | }; 44 | ``` 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /questions/278md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 278. First Bad Version 2 | 3 | ##題目 4 | You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad. 5 | 6 | Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, which causes all the following ones to be bad. 7 | 8 | You are given an API bool isBadVersion(version) which will return whether version is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API. 9 | 10 | ##翻譯 11 | 你是一個產品經理,目前正帶領一個團隊開發新產品,不幸的是,如果有一個新版的產品沒通過測試,在這版本之後全部的新版本都不會通過測試。 12 | 13 | 假如你有n個版本的產品[1,2, ...,n],然後你想追蹤是從哪一個版本開始沒通過測試。 14 | 15 | 這邊有一個 isBadVersion(version) API可以判斷這個版本能不能通過測試。利用這個API實作一個functon來找到第一個壞掉的版本。 16 | 17 | 範例: 18 | 假如目前有5個版本,[1,2,3,4,5],從第4個版本開始都是壞掉的,一個一個版本丟入API驗證會得到 [true,true,true,false,false]。 19 | 20 | ##思路 21 | 1. 最簡單的方法就是跑迴圈,將毎個版本丟入 isBadVersion中判斷,直到發現壞掉的版本,事情沒那麼美好,這種寫法會超過時間無法通過測試,因此需要另外想一個更快的演算法。 22 | 2. 以上面n=5,版本4之後就壞掉為例,我們可以把用 isBadVersion之後的版本陣列想像成[1,1,1,0,0],簡單說就是要找出第一個0出現的位置,其實就是猜數字之類的遊戲 23 | 3. 這邊用二分搜尋法來尋找第一個0,一開始最大值max=n,最小值min=1,搜尋的位置為mid = (max+min)/2, 24 | 如果 isBadVersion(mid)回傳true,代表壞掉的版本在mid之後,因此min = mid+1,反之亦然,一直搜尋到min>max,mid表示找到第一個壞掉的版本 25 | 26 |
27 | example: 28 | [1,2,3,4,5] --> [1,1,1,0,0] 29 | max = 5, min = 1 -> mid = 3 isBadVersion(3) = true 30 | min = mid+1 = 4 -> mid = 4 isBadVersion(4) = false 31 | max = mid = 4 -> max > min == false, end loop 32 |33 | 34 | ##解題 35 | ``` 36 | /** 37 | * Definition for isBadVersion() 38 | * 39 | * @param {integer} version number 40 | * @return {boolean} whether the version is bad 41 | * isBadVersion = function(version) { 42 | * ... 43 | * }; 44 | */ 45 | 46 | /** 47 | * @param {function} isBadVersion() 48 | * @return {function} 49 | */ 50 | var solution = function(isBadVersion) { 51 | 52 | /** 53 | * @param {integer} n Total versions 54 | * @return {integer} The first bad version 55 | */ 56 | return function(n) { 57 | var min = 0 ; 58 | var max = n ; 59 | var mid; 60 | 61 | // 用二分法進行搜尋,減少loop次數 62 | while(max > min){ 63 | mid = min+parseInt((max-min)/2); 64 | if(isBadVersion(mid)){ 65 | max = mid; 66 | } else { 67 | min = mid+1; 68 | } 69 | } 70 | 71 | return max; 72 | }; 73 | }; 74 | ``` 75 | 76 | ##失敗的解法 77 | ``` 78 | /** 79 | * @param {function} isBadVersion() 80 | * @return {function} 81 | */ 82 | var solution = function(isBadVersion) { 83 | 84 | /** 85 | * @param {integer} n Total versions 86 | * @return {integer} The first bad version 87 | */ 88 | return function(n) { 89 | 90 | for(var i = 0 ; i <= n ; i++){ 91 | if(isBadVersion(i)){ 92 | return i; 93 | } 94 | } 95 | } 96 | } 97 | ``` -------------------------------------------------------------------------------- /questions/27md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 27. Remove Element 2 | 3 | 4 | ##題目 5 | Given an array and a value, remove all instances of that value in place and return the new length. 6 | 7 | Do not allocate extra space for another array, you must do this in place with constant memory. 8 | 9 | The order of elements can be changed. It doesn't matter what you leave beyond the new length. 10 | 11 | Example: 12 | Given input array nums = [3,2,2,3], val = 3 13 | 14 | Your function should return length = 2, with the first two elements of nums being 2. 15 | 16 | ##翻譯 17 | 給一個陣列跟一個數字,移除陣列中所有跟數字相同的元素。 18 | 19 | 不可以使用另外的陣列來處理,全部的操作都要在同一個陣列中。 20 | 21 | 陣列中的元素可以隨意排序。 22 | 23 |
24 | 範例: 25 | nums = [3, 1, 2, 3, 2], val = 3 26 | 應該要return 陣列的長度3,因為裡面的3被移除後剩[1,2,2]. 27 |28 | 29 | ##思路 30 | 這跟 [LeetCode 283. Move Zeroes](283md.md) 很像,差別在於283移除的是0,這題移除的是特定數字,如果283有寫出來,這題應該難不倒你。 31 | 32 | ##解題 33 | ``` 34 | /** 35 | * @param {number[]} nums 36 | * @param {number} val 37 | * @return {number} 38 | */ 39 | var removeElement = function(nums, val) { 40 | if(nums.length == 0) return nums.length; 41 | if(nums.indexOf(val) < 0) return nums.length; 42 | 43 | var count = 0; 44 | for(var i = 0, max = nums.length; i
13 | Secret number: "1807" 14 | Friend's guess: "7810" 15 |16 | Hint: 1 bull and 3 cows. (The bull is 8, the cows are 0, 1 and 7.) 17 | Write a function to return a hint according to the secret number and friend's guess, use A to indicate the bulls and B to indicate the cows. In the above example, your function should return "1A3B". 18 | 19 | Please note that both secret number and friend's guess may contain duplicate digits, for example: 20 |
21 | Secret number: "1123" 22 | Friend's guess: "0111" 23 |24 | In this case, the 1st 1 in friend's guess is a bull, the 2nd or 3rd 1 is a cow, and your function should return "1A1B". 25 | You may assume that the secret number and your friend's guess only contain digits, and their lengths are always equal. 26 | 27 | ##翻譯 28 | 這題目敘述有點長,我記得以前這是以前堂哥跟我玩的(猜數字遊戲)[http://codepen.io/skyyen999/full/VedwqQ/],上面那一大串英文的意思是,這邊有一串隱藏的號碼(secret number),然後你朋友會猜一串號碼, 29 | 如果號碼數字與位置都對了,給一個bull,數字對但位置不對,給一個cow。 30 | 31 | 範例: 32 |
33 | Secret number: "1807" 34 | Friend's guess: "7810" 35 |36 | 上面範例可以發現8得到一個bull,剩下1,0,7得到一個cow,所以得到1A3B 37 | 38 |
39 | Secret number: "1123" 40 | Friend's guess: "0111" 41 |42 | 第二個範例,第二個1得到一個bull,Friend's guess 第三個1得到一個cow(比對secret number的第一個1),因此得到1A1B 43 | 44 | 45 | ##思路 46 | 1. 先判斷有幾個bull(位置數字都一樣) 47 | 2. 出現bull將secret number跟friend's guess這個位子上的數字移除 48 | 3. 剩下的字串再來判斷有幾個cow 49 | 50 | ##解題 51 | ``` 52 | /** 53 | * @param {string} secret 54 | * @param {string} guess 55 | * @return {string} 56 | */ 57 | var getHint = function(secret, guess) { 58 | var bull = 0; 59 | var cow = 0; 60 | 61 | // 儲存secret[n],guess[n]數字不同的元素 62 | var skeep = []; 63 | var gkeep = []; 64 | 65 | //先判斷位置數字都一樣,剩下的用sK, gK來儲存 66 | for(var i in guess){ 67 | // 位置數字都一樣,bull++ 68 | if(secret[i] == guess[i]){ 69 | bull++; 70 | } else { 71 | skeep.push(secret[i]); 72 | gkeep.push(guess[i]); 73 | } 74 | } 75 | 76 | // 因為bull已經處理過,這邊只要gkeep內的元素出現在skeep內,代表就是一個cow 77 | for(var j in gkeep){ 78 | var findIndex = skeep.indexOf(gkeep[j]); 79 | if(findIndex != -1){ 80 | cow++; 81 | skeep[findIndex] = null; 82 | } 83 | } 84 | 85 | return bull+ "A" + cow + "B" 86 | }; 87 | ``` 88 | -------------------------------------------------------------------------------- /questions/2md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 2. Add Two Numbers 2 | 3 | ##題目 4 | You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order 5 | and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. 6 | 7 | Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) 8 | Output: 7 -> 0 -> 8 9 | 10 | ##翻譯 11 | 有兩個連結陣列分別代表兩個非負整數,他們的位數是反向儲存(越前面的節點位數越低),毎一個節點代表一個位數,將這兩個連結陣列加總後以連結陣列形式回傳。 12 | 13 | 範例: 14 | Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) 15 | Output: 個位數為2與5,相加為7 ; 十位數為4+6 = 10,需要進位 ; 百位數為3 + 4 + 1(進位) = 8,結果為 7->0->8 16 | 17 | ##思路 18 | 1. 就只是用一個新的linked list來儲存相加後的結果 19 | 2. 要注意的就是list1跟list2長度可能不一樣 20 | 3. 另外就是相加後可能比9還大,需要考慮進位的情況 21 | 22 | ##解題 23 | ``` 24 | /** 25 | * Definition for singly-linked list. 26 | * function ListNode(val) { 27 | * this.val = val; 28 | * this.next = null; 29 | * } 30 | */ 31 | /** 32 | * @param {ListNode} l1 33 | * @param {ListNode} l2 34 | * @return {ListNode} 35 | */ 36 | var addTwoNumbers = function(l1, l2) { 37 | var list = new ListNode(0); //儲存輸出的結果,因為list的指針要不斷往後移,因此用一個假節點方便操作 38 | var result = list; // 使用一個ListNode來儲存相加的結果 39 | 40 | var sum,carry = 0; // carry用來處理進位 41 | 42 | //當 list1, list2 都沒有值,而且carry也為0的時候才結束迴圈 43 | while(l1 || l2 || carry > 0){ 44 | sum = 0; 45 | 46 | // list1與list2長度可能不同,分開處理 47 | if(l1!== null){ 48 | sum += l1.val; 49 | l1 = l1.next; 50 | } 51 | 52 | if(l2!==null){ 53 | sum += l2.val; 54 | l2 = l2.next; 55 | } 56 | 57 | // 如果之前有進位,carry = 1;沒有的話carry = 0 58 | sum += carry; 59 | list.next = new ListNode(sum%10); //相加如果超過9,只能留下個位數放入結果list,十位數的地方進位 60 | carry = parseInt(sum/10); 61 | 62 | // list指標向後 63 | list = list.next; 64 | } 65 | // 因為第一個節點為假節點,跳過 66 | return result.next; 67 | } 68 | ``` 69 | 70 | ##用遞迴解 71 | ``` 72 | var addTwoNumbers = function(l1, l2) { 73 | 74 | var list = new ListNode(0); 75 | var result = list; // 使用一個ListNode來儲存相加的結果 76 | 77 | add(l1,l2,0); 78 | return result.next; 79 | 80 | function add(l1,l2,gap){ 81 | var sum = 0; 82 | if(l1 === null && l2 === null && gap === 0){ 83 | return 0; 84 | } 85 | 86 | if(l1 !== null){ 87 | sum += l1.val; 88 | l1 = l1.next; 89 | } 90 | 91 | if(l2 !== null){ 92 | sum += l2.val; 93 | l2 = l2.next; 94 | } 95 | sum += gap; 96 | list.next = new ListNode(sum%10); 97 | gap = parseInt(sum/10); 98 | list = list.next; 99 | add(l1,l2,gap); 100 | } 101 | }; 102 | ``` -------------------------------------------------------------------------------- /questions/303md.md: -------------------------------------------------------------------------------- 1 | # 303. Range Sum Query - Immutable 2 | 3 | ##題目 4 | Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive. 5 |
6 | Example: 7 | Given nums = [-2, 0, 3, -5, 2, -1] 8 | 9 | sumRange(0, 2) -> 1 10 | sumRange(2, 5) -> -1 11 | sumRange(0, 5) -> -3 12 |13 | Note: 14 | You may assume that the array does not change. 15 | There are many calls to sumRange function. 16 | 17 | ##翻譯 18 | 給一個int陣列,寫一個sumRange方法找尋陣列中元素i~j的總和。 19 | 20 | 範例: 21 | nums = [-2, 0, 3, -5, 2, -1] 22 | sumRange(0, 2) -> 1 23 | sumRange(2, 5) -> -1 24 | sumRange(0, 5) -> -3 25 | 26 | 注意:你不能改變傳入陣列的值,然後sumRange會被忽叫很多次。 27 | 28 | ##思路 29 | 1. 一開始的想法是sumRange被忽叫時就跑迴圈把i到j之間全部的值加起來,這很簡單,不過果然超時(TLE)了 30 | 2. 換個想法,sumRange會被忽叫很多次,因此在裡面寫迴圈不是一個好辦法 31 | 3. 這邊先用另外一個array來儲存a[0]~a[i]的加總,之後要取加總只要取array[j]-array[i-1]就可以 4. 以 [-2, 0, 3, -5, 2, -1] 為例,array = [-2,-2,1,-4,2,1] 32 | 5. sumRange(0, 2) --> i = 0,因此只要直接取array[j] = 2 33 | 6. sumRange(2, 5) --> 取array[5] = -1,array[1] = 0, sum = array[j]-array[i-1] = -1 34 | 35 | ##解題 36 | ``` 37 | /** 38 | * @constructor 39 | * @param {number[]} nums 40 | */ 41 | var NumArray = function(nums) { 42 | var sum = 0; 43 | this.array = []; 44 | // 先將加總存到一個array 45 | for(var i in nums){ 46 | sum += nums[i]; 47 | this.array.push(sum); 48 | } 49 | }; 50 | 51 | /** 52 | * @param {number} i 53 | * @param {number} j 54 | * @return {number} 55 | */ 56 | NumArray.prototype.sumRange = function(i, j) { 57 | if(i == 0){ 58 | return this.array[j]; 59 | } 60 | //取出的時候,只要取array[0]到array[j]的加總sumJ 減去 array[0]到array[i]的加總,就是i到j的加總 61 | return this.array[j] - this.array[i-1]; 62 | }; 63 | 64 | 65 | /** 66 | * Your NumArray object will be instantiated and called as such: 67 | * var numArray = new NumArray(nums); 68 | * numArray.sumRange(0, 1); 69 | * numArray.sumRange(0, 2); 70 | */ 71 | ``` 72 | 73 | -------------------------------------------------------------------------------- /questions/326md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 326. Power of Three 2 | 3 | ##題目 4 | Given an integer, write a function to determine if it is a power of three. 5 | 6 | Follow up: 7 | Could you do it without using any loop / recursion? 8 | ##翻譯 9 | 判斷一個整數是否是3的次方數。 10 | 11 | 進階: 12 | 不使用迴圈,遞迴解題? 13 | 14 | ##思路 15 | 不管進階的話跟[LeetCode 231. Power of Two](questions/231md.md)解法是一模一樣的。 16 | 因此只要不斷的把這個數除3,如果發現餘數不是0,就可以判斷這個數不是3的次方數 17 | 18 | ##解題 19 | ``` 20 | /** 21 | * @param {number} n 22 | * @return {boolean} 23 | */ 24 | var isPowerOfThree = function(n) { 25 | while(n>2){ 26 | if(n%3 !== 0) return false; 27 | n = parseInt(n/3); 28 | } 29 | 30 | return n==1; 31 | }; 32 | ``` -------------------------------------------------------------------------------- /questions/342md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 342. Power of Four 2 | 3 | ##題目 4 | Given an integer (signed 32 bits), write a function to check whether it is a power of 4. 5 | 6 | Example: 7 | Given num = 16, return true. Given num = 5, return false. 8 | 9 | Follow up: Could you solve it without loops/recursion? 10 | 11 | ##翻譯 12 | 判斷一個32bits的int整數是否為4的倍數。 13 | 14 | 進階:不用迴圈,遞迴解題。 15 | ##思路 16 | 一直除4,如果出現餘數,就不是4的整數。 17 | 18 | ##解題 19 | ``` 20 | /** 21 | * @param {number} num 22 | * @return {boolean} 23 | */ 24 | var isPowerOfFour = function(num) { 25 | if(num <= 0 ) return false; 26 | if(num == 1) return true; 27 | if(num%2 == 1) return false; 28 | 29 | while(num >= 4){ 30 | if(num%4!=0) return false; 31 | num = parseInt(num/4); 32 | } 33 | 34 | return num==1 ; 35 | }; 36 | ``` 37 | -------------------------------------------------------------------------------- /questions/344md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 344. Reverse String 2 | 3 | ##題目 4 | Write a function that takes a string as input and returns the string reversed. 5 | 6 | Example: 7 | Given s = "hello", return "olleh". 8 | 9 | ##翻譯 10 | 將一個字串反轉後回傳。 11 | 12 | 範例: 13 | s= "hello", return "olleh" 14 | 15 | ##思路 16 | 這題很簡單,應該是所有題目最簡單的一題,如果你解不出來建議不要往下看,回頭在重新學一下怎麼寫程式。 17 | 18 | 這題的解法是這樣,將字串拆成一個陣列,然後將陣列從後面開始串成一個字串並回傳。 19 | ex. "hello" -> 拆開['h','e','l','l','o'] -> 'o'+'l'+'l'+'e'+'h' 20 | 21 | ##解題 22 | ``` 23 | var reverseString = function(s) { 24 | var result = ""; //回傳的字串 25 | var ary = s.split(""); //字串拆成陣列 26 | 27 | for(var i = ary.length-1 ; i >= 0 ; i--){ 28 | result = result + ary[i]; //從後面串回字串 29 | } 30 | return result; 31 | }; 32 | ``` 33 | 34 | ##進階 35 | 在陣列內直接將頭尾元素交換,接著交換第二個元素與倒數第二個元素,這樣的做法只要跑一半的迴圈就可以,速度上會快很多。 36 | 下面範例因為切成array來做,所以實際上速度會比較慢。 37 | 38 | >未交換前 ['h','e','l','l','o'] 39 | 第1次交換 ['**h**','e','l','l','**o**'] o,h互換 ['**o**','e','l','l','**h**'] 40 | 第2次交換 ['o','**e**','l','**l**','h'] e,l互換 ['o','**l**','l','**e**','h'] 41 | 42 | 43 | ``` 44 | /** 45 | * @param {string} s 46 | * @return {string} 47 | */ 48 | var reverseString = function(s) { 49 | var result = ""; 50 | var ary = s.split(""); 51 | for(var i = 0, max = (ary.length-1)/2 ; i < max ; i++){ 52 | var temp = ary[i]; 53 | ary[i] = ary[ary.length - 1 - i]; 54 | ary[ary.length - 1 - i] = temp; 55 | } 56 | return ary.join(""); 57 | }; 58 | ``` -------------------------------------------------------------------------------- /questions/345md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 345. Reverse Vowels of a String 2 | 3 | ##題目 4 | Write a function that takes a string as input and reverse only the vowels of a string. 5 | 6 | Example 1: 7 | Given s = "hello", return "holle". 8 | 9 | Example 2: 10 | Given s = "leetcode", return "leotcede". 11 | 12 | Note: 13 | The vowels does not include the letter "y". 14 | ##翻譯 15 | 給一個英文字串,將裡面的母音字母反轉。 16 | 17 | 範例1: 18 | Given s = "hello", return "holle". 19 | 20 | 範例2: 21 | Given s = "leetcode", return "leotcede". 22 | 23 | 注意: 24 | y不算在母音字母中。 25 | 26 | ##思路 27 | 1. 先將字串中的母音儲存在array 28 | 2. 重新搜索字串中的母音,將array理面的字元依相反順序取代字串中的母音 29 | 30 | ##解題 31 | ``` 32 | /** 33 | * @param {string} s 34 | * @return {string} 35 | */ 36 | var reverseVowels = function(s) { 37 | 38 | var vowels = []; // 儲存找到的母音 39 | 40 | // 找母音 41 | for(var i = 0 ; i< s.length ; i++){ 42 | if((/^[aeiou]$/i).test(s[i])){ 43 | vowels.push(s[i]); 44 | } 45 | } 46 | 47 | var v = vowels.length - 1; 48 | // 因為之前是用array儲存找到的母音,所以把本來的字串也轉成array 49 | var sAry = s.split(""); 50 | 51 | // 用之前找到的array取代母音 52 | for(var j = 0 ; j < sAry.length ; j++){ 53 | if((/^[aeiou]$/i).test(sAry[j])){ 54 | sAry[j] = vowels[v--]; 55 | } 56 | } 57 | 58 | return sAry.join(""); 59 | }; 60 | ``` 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /questions/349md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 349. Intersection of Two Arrays 2 | 3 | ##題目 4 | Given two arrays, write a function to compute their intersection. 5 | 6 | Example: 7 | Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2]. 8 | 9 | Note: 10 | Each element in the result must be unique. 11 | The result can be in any order. 12 | 13 | ##翻譯 14 | 尋找兩個陣列的交集。 15 | 16 | 範例: 17 | nums1 = [1, 2, 2, 1],nums2 = [2, 2],return [2]。 18 | 19 | 注意: 20 | 同樣的數字只出現一次,回傳的陣列內容不限排序。 21 | 22 | ##思路 23 | 1. 先判斷nums1與nums2長度誰比較短,我們就稱它叫ary拿來跑迴圈,較長的陣列叫store。 24 | 2. ary[i]如果可以在store中找到值,表示這是交集的數字。 25 | 3. 判斷結果陣列(result)是否已經有交集數字,如果沒有就新增到結果陣列(result)中。 26 | 27 | ##解題 28 | ``` 29 | /** 30 | * @param {number[]} nums1 31 | * @param {number[]} nums2 32 | * @return {number[]} 33 | */ 34 | var intersection = function(nums1, nums2) { 35 | var result = []; 36 | var store; // 長array 37 | var ary; // 短array 38 | 39 | // 判斷nums1,nums2長度 40 | if(nums1.length > nums2.length){ 41 | store = nums1; 42 | ary = nums2; 43 | } else { 44 | store = nums2; 45 | ary = nums1; 46 | } 47 | 48 | // 只需需要跑較短的array就行 49 | for(var i = 0 ; i < ary.length ; i++){ 50 | var value = ary[i]; 51 | // 如果可以在長array中找到目前的值,而且在結果array中找不到,代表這個值是新的交集 52 | if(store.indexOf(value) >= 0 && result.indexOf(value) == -1){ 53 | result.push(value); 54 | } 55 | } 56 | return result; 57 | }; 58 | ``` 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /questions/350md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 350. Intersection of Two Arrays II 2 | 3 | ##題目 4 | Given two arrays, write a function to compute their intersection. 5 | 6 | Example: 7 | Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2, 2]. 8 | 9 | Note: 10 | * Each element in the result should appear as many times as it shows in both arrays. 11 | * The result can be in any order. 12 | 13 | Follow up: 14 | * What if the given array is already sorted? How would you optimize your algorithm? 15 | * What if nums1's size is small compared to nums2's size? Which algorithm is better? 16 | * What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once? 17 | 18 | 19 | ##翻譯 20 | 尋找兩個陣列的交集。 21 | 22 | 範例: 23 | nums1 = [1, 2, 2, 1],nums2 = [2, 2], return [2,2] 24 | 25 | 注意: 26 | * 同樣的數字在回傳的陣列中可重複出現 27 | * 回傳的陣列可以不管裡面的數字排序 28 | 29 | 進階: 30 | * 如果陣列已經排序過,如何最佳化演算法? 31 | * 如果nums1長度小於nums2長度,如何最佳化演算法? 32 | * 如果nums2儲存在光碟上,所以無法一次讀盡所有的元素,要怎麼處理? 33 | 34 | ##思路 35 | 不管進階的部分,這題跟[LeetCode 349. Intersection of Two Arrays](questions/349md.md)很像,只是交集的數字可重複出現。 36 | 37 | 先找出哪個陣列較長為store,較短的為ary,ary[i]如果可以在store中找到值,表示這是交集的數字,將這數字放入回傳陣列,移除store中第一個交集數字。 38 | 39 | ##解題 40 | ``` 41 | var store, array; 42 | var number = []; 43 | if(nums1.length > nums2.length){ 44 | store = nums1; 45 | array = nums2; 46 | } else { 47 | store = nums2; 48 | array = nums1; 49 | } 50 | 51 | for(var i = 0; i < array.length ; i++){ 52 | var v = array[i]; 53 | if(store.indexOf(v) >= 0){ 54 | store[store.indexOf(v)] = null; 55 | number.push(v); 56 | } 57 | } 58 | return number; 59 | ``` 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /questions/36md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 36. Valid Sudoku 2 | ##題目 3 | Determine if a Sudoku is valid, according to: [Sudoku Puzzles - The Rules.](http://sudoku.com.au/TheRules.aspx) 4 | 5 | The Sudoku board could be partially filled, where empty cells are filled with the character '.'. 6 |  7 | ##翻譯 8 | 判斷是不是一個合法的數獨,規則請參考 [Sudoku Puzzles - The Rules.](http://sudoku.com.au/TheRules.aspx) 9 | 10 | 不用填滿數獨,只要判斷是否合法就可以,空的格子在這邊用'.'來代替。 11 | 12 | ##思路 13 | 1. 數獨是否合法,每一個格子需要判斷的有,同row的數字不能重複,同column的數字不能重複,同一個九宮格box內不能重複三種情況要考慮 14 | 2. 將每個row,column,box都變成一行陣列,再寫一個判斷陣列裡面是否有重複值的validRepeat function 15 | 3. 讀一個數獨board使用雙層的for loop,每次讀一個row,直接把row丟進validRepeat裡面判斷是否有重複的值 16 | 3. board[0][0~8] <--第一個row內的值 , board[0~8][0] <--第一個column內的值 17 | 4. 判斷[i,j]第幾個九宮格用 parseInt(i/3)x3+j/3,將九宮格的值用陣列儲存,最後再一個一個判斷是否有重複的值 18 | ##解題 19 | ``` 20 | /** 21 | * @param {character[][]} board 22 | * @return {boolean} 23 | */ 24 | var isValidSudoku = function(board) { 25 | // 判斷九宮格內是否有重複數字用 26 | var boxs = [[],[],[],[],[],[],[],[],[]]; 27 | 28 | 29 | for(var i = 0 ; i < 9 ; i++){ 30 | // 判斷column是否有重複數字用 31 | var cRow = []; 32 | 33 | // 直接將row丟進去判斷是否有重複 34 | if(!validRepeat(board[i])){ 35 | return false; 36 | } 37 | 38 | for(var j = 0 ; j < 9 ; j++){ 39 | cRow.push(board[j][i]); // board[j = 0~8][i = 0] => 等於把第一個columns的值一個一個抓出來 40 | 41 | // 根據i,j判斷目前位子是屬於哪個九宮格, boxId = 3*(i/3取整數) + (j/3取整數) 42 | var boxId = 3*parseInt(i/3) +parseInt(j/3); 43 | boxs[boxId].push(board[i][j]); 44 | } 45 | 46 | //console.log(cRow) 47 | 48 | if(!validRepeat(cRow)){ 49 | return false; 50 | } 51 | } 52 | //console.log(boxs) 53 | 54 | // 判斷九宮格內是否有重複的值 55 | for(var k = 0 ; k < 9 ; k++){ 56 | if(!validRepeat(boxs[k])){ 57 | return false; 58 | } 59 | } 60 | 61 | 62 | return true; 63 | 64 | // 使用一個 65 | function validRepeat(array){ 66 | var map = []; 67 | for(var i = 0; i < 9 ; i++){ 68 | if(array[i] == ".") continue; 69 | if(map.indexOf(array[i]) == -1){ 70 | map.push(array[i]); 71 | } else { 72 | return false; 73 | } 74 | } 75 | return true; 76 | } 77 | }; 78 | ``` 79 | -------------------------------------------------------------------------------- /questions/371md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 371. Sum of Two Integers 2 | 3 | ##題目 4 | Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -. 5 | 6 | ##翻譯 7 | 計算a,b的加總,但是不能用+-符號。 8 | 9 | ##思路 10 | 不用加減改用位元做運算,其實我也不會阿,而且直接回傳a+b還是會通過的,如果你被這題卡住,建議先跳過。以下單純學習分享。 11 | 12 | 1. 假設輸入的數字為a=3(0011), b=9(1001) 13 | 2. 相加不考慮進位 a = a^b = (0011)^(1001) = 1010 14 | 3. 相加只考慮進位 carry =a&b = (0011)^(1001) = 0001 進位值 15 | 4. b = 0001 << 1 = 0010 進位 16 | 5. 第一輪後 a= 10(1010), b = 2(0010) 17 | 6. 相加不考慮進位 a = a^b = (1010)^(0010) = 1000 18 | 7. 相加只考慮進位 carry =a&b = (1010)^(0010) = 0010 進位值 19 | 8. b = 0001 << 1 = 0100 進位 20 | 9. 第二輪後 a= 8(1000), b = 4(0010) 21 | 10. 相加不考慮進位 a = a^b = (1000)^(0100) = 1100 22 | 11. 相加只考慮進位 carry =a&b = (1010)^(0010) = 0000 進位值 23 | 12. b = 0000 << 1 = 0 24 | 13. b=0,相加完成, a = 1100 = 12 25 | 26 | ##解題 27 | ``` 28 | var getSum = function(a, b) { 29 | if(b==0){return a}; 30 | if(a==0){return b}; 31 | 32 | while(b!=0){ 33 | var carry = a&b; //進位值 34 | 35 | a = a^b; //相加 36 | 37 | b = carry << 1; //進位 38 | } 39 | return a; 40 | }; 41 | ``` 42 | -------------------------------------------------------------------------------- /questions/374md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 374. Guess Number Higher or Lower 2 | ##題目 3 | We are playing the Guess Game. The game is as follows: 4 | 5 | I pick a number from 1 to n. You have to guess which number I picked. 6 | 7 | Every time you guess wrong, I'll tell you whether the number is higher or lower. 8 | 9 | You call a pre-defined API guess(int num) which returns 3 possible results (-1, 1, or 0): 10 |
11 | -1 : My number is lower 12 | 1 : My number is higher 13 | 0 : Congrats! You got it! 14 | 15 | Example: 16 | n = 10, I pick 6. 17 | Return 6. 18 |19 | 20 | ##翻譯 21 | 給一個n值,猜一個1~n之間神秘數字x,根據猜測的結果回傳值,如果回傳-1代表神秘數字比你猜的還低,回傳1代表比你猜的還高,回傳0代表你猜對了。最後你要回傳x到底是多少。 22 | 23 | 範例: 24 | * n = 1000,神秘數字是987 ,猜500,得到-1 25 | * 猜 1000,得到 1 26 | * 猜 987,得到 0, 因此最後要回傳答案 987 27 | 28 | ##思路 29 | 30 | 1. 最小值為min,最大值為max,猜測值 g = (min+max)/2 31 | 2. 一開始min = 1, max = n , g = (1+n) /2 32 | 2. 如果得到1, min = g 33 | 3. 如果得到-1, max = g 34 | 4. 重複以上步驟值到猜到為止,因為這提沒提供javascript,只好用java來解 35 | 36 | ##解題 37 | ``` 38 | /* The guess API is defined in the parent class GuessGame. 39 | @param num, your guess 40 | @return -1 if my number is lower, 1 if my number is higher, otherwise return 0 41 | int guess(int num); */ 42 | 43 | public class Solution extends GuessGame { 44 | public int guessNumber(int n) { 45 | if(guess(n) == 0){ 46 | return n; 47 | } 48 | 49 | int min = 1; // 最小為1 50 | int max = n; // 最大為n 51 | int g = min+(max-min)/2; //先猜(min+max)/2 52 | int result = guess(g); 53 | 54 | while(max > min){ 55 | 56 | // 猜的值太小,min=g 57 | if(result == 1){ 58 | min = g; 59 | } 60 | 61 | // 猜的值太大,max=g 62 | if(result == -1){ 63 | max = g; 64 | } 65 | 66 | // equal with (min+max)/2,but use min+(max-min)/2 could avoid max+min > Integer.max 67 | g = min+(max-min)/2; 68 | 69 | result = guess(g); 70 | } 71 | 72 | return g; 73 | 74 | } 75 | } 76 | ``` 77 | -------------------------------------------------------------------------------- /questions/38md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 38. Count and Say 2 | 3 | ##題目 4 | The count-and-say sequence is the sequence of integers beginning as follows: 5 | 1, 11, 21, 1211, 111221, ... 6 | 7 | 1 is read off as "one 1" or 11. 8 | 11 is read off as "two 1s" or 21. 9 | 21 is read off as "one 2, then one 1" or 1211. 10 | Given an integer n, generate the nth sequence. 11 | 12 | Note: The sequence of integers will be represented as a string. 13 | 14 | ##翻譯 15 | 這是一個算完說出來的序列,序列如下: 16 | 1, 11, 21, 1211, 111221, ... 17 | 18 |
19 | 1 讀做 1個1, 所以下一個變成 11 20 | 11 讀做 2個1, 也就是21 21 | 21 讀做 1個2 1個1,得到1211 22 | 1211 1個1,1個2,2個1 111221 23 |24 | 25 | ##思路 26 | 相信這題很多人跟我一樣,看懂題目後就覺得簡單了,直接看下面的code就行。 27 | 28 | ##解題 29 | ``` 30 | /** 31 | * @param {number} n 32 | * @return {string} 33 | */ 34 | var countAndSay = function(n) { 35 | if(n <= 1) return "1"; 36 | 37 | var countSay = '1'; 38 | 39 | for(var i = 2 ; i <= n ; i++){ 40 | var num = countSay.charAt(0); //從開頭開始數 41 | var temp = countSay; 42 | var count = 1; 43 | 44 | countSay = ''; // 清空儲存這輪數完的字串 45 | 46 | 47 | for(var j = 1 ; j < temp.length; j++){ 48 | // 數字相同,count++ 49 | if(temp.charAt(j) == num){ 50 | count++; 51 | } else { 52 | // 數字不同,將目前的count與num加到字串,更新num,新的num從1開始數起 53 | countSay += count; 54 | countSay += num; 55 | num = temp.charAt(j); 56 | count = 1; 57 | } 58 | } 59 | countSay += count; 60 | countSay += num; 61 | } 62 | return countSay; 63 | 64 | }; 65 | ``` 66 | -------------------------------------------------------------------------------- /questions/58md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 58. Length of Last Word 2 | 3 | ##題目 4 | Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string. 5 | 6 | If the last word does not exist, return 0. 7 | 8 | Note: A word is defined as a character sequence consists of non-space characters only. 9 | 10 | For example, 11 | Given s = "Hello World", 12 | return 5. 13 | 14 | ##翻譯 15 | 給一個字串s,其中包含大小寫字母與空白' ',回傳最後一個單字的長度,如果沒有最後一個單字,回傳0。 16 | 17 | 注意:單字的定義是由一串連續中間沒空白的字元所組成。 18 | 19 | 範例: 20 | Given s = "Hello World",最後一個單字為world,長度為5。 21 | 22 | ##思路 23 | 1. 用split把字串拆成陣列,例如 "Hello World " -> ['Hello','World', ' '] 24 | 2. 取陣列最後一個元素,上面範例取出來的是空字串' ' 25 | 3. 空字串不是我們要的單字,往前再取到'World',因此最後一個單字長度為5 26 | 27 | ##解題 28 | ``` 29 | /** 30 | * @param {string} s 31 | * @return {number} 32 | */ 33 | var lengthOfLastWord = function(s) { 34 | var ary = s.split(/\s/); //使用regex將字串切開 35 | 36 | if(s.length == 0) return 0; 37 | if(ary.length == 0) return 0; 38 | 39 | // 從陣列最後面取出單字,如果是空白' '就不是單字,所以繼續往前找 40 | while(ary.length > 0){ 41 | var v = ary.pop(); 42 | if(v.length > 0){ 43 | return v.length; 44 | } 45 | 46 | } 47 | 48 | return 0; 49 | }; 50 | ``` 51 | -------------------------------------------------------------------------------- /questions/66md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 66. Plus One 2 | 3 | ##題目 4 | Given a non-negative number represented as an array of digits, plus one to the number. 5 | 6 | The digits are stored such that the most significant digit is at the head of the list. 7 | 8 | ##翻譯 9 | 給一包含非數整數的陣列,其中每一個值代表該位數的值,對這個陣列加1。 10 | 11 | 範例: 12 | 19 = [1,9] , 19+1 = 20 = [2,0]。 13 | 14 | ##思路 15 | 1. 陣列最後一個數是個位數,所以從後面開始讀,個位數+1後,如果有進位,儲存進位值,val = 0,沒進位直接存儲。 16 | 2. 處理十位數,如果個位數有進位,十位數+1,再判斷十位數是否有進位 17 | 3. 重複上面動做值到陣列結束 18 | 19 | ##解題 20 | ``` 21 | /** 22 | * @param {number[]} digits 23 | * @return {number[]} 24 | */ 25 | var plusOne = function(digits) { 26 | // 判斷相加後是否需進位 27 | var carry = 0; 28 | 29 | for(var i = digits.length - 1 ; i >= 0 ; i--){ 30 | // 目前位數 = 目前位數+前面是否進位 31 | digits[i]= digits[i] + carry; 32 | 33 | // list最後一個數字,也就是個位數,給他+1 34 | if(i == digits.length - 1 ){ 35 | digits[i] = digits[i] + 1; 36 | } 37 | 38 | // 如果目前這個位數等於10(因為只+1,所以不會超過10),進位 39 | if(digits[i] == 10){ 40 | digits[i] = 0; 41 | carry = 1; 42 | } else { 43 | carry = 0; 44 | } 45 | } 46 | 47 | // 最後如果有進位 48 | if(carry == 1){ 49 | digits.unshift(carry); 50 | } 51 | 52 | return digits; 53 | }; 54 | ``` 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /questions/67md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 67. Add Binary 2 | 3 | ##題目 4 | Given two binary strings, return their sum (also a binary string). 5 | 6 | For example, 7 | a = "11" 8 | b = "1" 9 | Return "100". 10 | 11 | ##翻譯 12 | 給兩個字元字串,回傳他們的總和(以字元字串回傳)。 13 | 14 | 範例: 15 | a = '11' 16 | b = '1' 17 | return '100' 18 | 19 | ##思路 20 | 1. 一開始的想法是將a,b轉為數字,相加後再轉回bits,程式碼在下面,不過題目給的string長度轉成int時會超過int max,所以這個方法不能用 21 | 2. 改用純字串來處理,先處理位數一樣的部分,ex. "111"+"10" ,先處理"11"+"10" 22 | 4. 以 "11"+"10"為例,個位數1+0=1; 十位數1+1=2,因為bits是二進位,因此2->0,然後儲存進位資訊,這時候要回傳的字串為'10' 23 | 5. "111"最前面的"1"+剛才的進位1 = 2, 2-> 0 , 會傳字串為'010' 24 | 6. 因為剛才還有進位,所以要把進位的1加到字串前面,最後回傳'1010' 25 | 26 | ##解題 27 | ``` 28 | /** 29 | * @param {string} a 30 | * @param {string} b 31 | * @return {string} 32 | */ 33 | var addBinary = function(a, b) { 34 | // 使用字串來處理 35 | var sumStr = ""; 36 | var carry = 0; 37 | var longStr, shortStr; 38 | 39 | // 判斷a,b哪個字串比較長 40 | if(a.length > b.length){ 41 | longStr = a; 42 | shortStr = b; 43 | } else { 44 | longStr = b; 45 | shortStr = a; 46 | } 47 | 48 | longStr = longStr.split("").reverse().join(""); 49 | shortStr = shortStr.split("").reverse().join(""); 50 | 51 | // 將短字串加到長字串裡面,這邊先計算到短字串的位數,ex. "110" + "1111",這邊先處理 "110" + "111" 52 | for(var i = 0 ; i < shortStr.length ; i++) { 53 | var c = parseInt(shortStr.charAt(i))+parseInt(longStr.charAt(i)) + carry; 54 | // 二進位,相加大於1,就要進位 55 | if(c > 1){ 56 | carry = 1; 57 | c = c%2; 58 | } else { 59 | carry = 0; 60 | } 61 | 62 | sumStr = c + sumStr; 63 | } 64 | 65 | // 處理長字串剩下的字串 66 | for(var j = shortStr.length ; j < longStr.length ; j ++){ 67 | var c = parseInt(longStr.charAt(j)) + carry; 68 | if(c > 1){ 69 | carry = 1; 70 | c = c%2; 71 | } else { 72 | carry = 0; 73 | } 74 | sumStr = c + sumStr 75 | } 76 | 77 | // 如果加完後還有進位,要放到字串最前面 78 | return (carry == 1 ? carry : "") + sumStr; 79 | }; 80 | ``` 81 | 82 | ##失敗的解題 83 | ``` 84 | var addBinary = function(a, b) { 85 | var sum = parseInt(a,2)+parseInt(b,2); 86 | var bitStr = ""; 87 | 88 | while(sum > 0){ 89 | bitStr = sum%2 + bitStr; 90 | sum = Math.floor(sum/2); 91 | } 92 | 93 | return bitStr == '' ? '0': bitStr ; 94 | } 95 | ``` -------------------------------------------------------------------------------- /questions/6md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 6. ZigZag Conversion 2 | 3 | ##題目 4 | The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) 5 |
6 | P A H N 7 | A P L S I I G 8 | Y I R 9 |10 | 11 | And then read line by line: "PAHNAPLSIIGYIR" 12 | Write the code that will take a string and make this conversion given a number of rows: 13 | 14 |
15 | string convert(string text, int nRows); 16 |17 | 18 | convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR". 19 | 20 | ##翻譯 21 | 字串"PAYPALISHIRING"經過Z字轉換後如圖所示,重組後變成"PAHNAPLSIIGYIR", 22 | 寫一個convert(string text, int nRows)來將傳入的字串text轉換成n行的Z字轉換。 23 | 24 | convert("PAYPALISHIRING", 3) 會回傳 "PAHNAPLSIIGYIR"。 25 | 26 | 這邊用另外一個範例來解釋會比較清楚: 27 | text = "ABCDEFGHIJKLMN", n = 4,排成Z字如下,因此轉換後的字串為 "AGMBFHLNCEIKDJ" 28 |
29 | A G M 30 | B F H L N 31 | C E I K 32 | D J 33 |34 | 35 | 36 | ##思路 37 | 1. 從上面nRows=3,nRows=4觀察可以知道,字母要回到第一列總共要經過 2*nRows - 2次變化,例如上面的例子A->G之間總共經過 2*4-2 = 6個字母 38 | 2. 用一個array來儲存毎一列的字母,上面範例最後array[0] = 'AGM' 39 | 3. n = 2*nRows - 2代表實際上經過的字母數,字母位置為i, i%n < nRows時,直接將字母放入array[i], 40 | 例如"B"的位置i為1,1%6 = 1, 將"B"放入array[1] 41 | 4. 當i%n >= nRows時, 放入的位置為 nRows-1 - (i%n) - nRows -1,整理一下可以寫成2*nRows - i%n - 2 42 | 例如上面的"F" [i=5, i%6 = 5], 5 > 4 因此"F"在array中的位置為 2*4 - 5 - 2 = 1, 43 | 因此將"F"放到array[1],也就是array[1] = "BF" 44 | 5. 最後將array內的字串結合回傳 45 | 46 | ##解題 47 | ``` 48 | /** 49 | * @param {string} s 50 | * @param {number} numRows 51 | * @return {string} 52 | */ 53 | var convert = function(s, numRows) { 54 | if(s == null) return ""; 55 | if(numRows == 1) return s; 56 | 57 | // 毎一輪的變化總共是numRows*2 - 2種 58 | var n = numRows*2 - 2; 59 | var array = []; 60 | 61 | // 創立一個有numRows元素的array 62 | for(var k = 0 ; k < numRows; k++){ 63 | array.push(""); 64 | } 65 | 66 | for(var i in s){ 67 | var lineNumber = i%n; 68 | if(lineNumber < numRows){ 69 | // i%n 比 numRows小,s[i]直接放入array 70 | array[lineNumber] += s[i]; 71 | } else { 72 | // 計算s[i]應該屬於array哪個位子 73 | //array[numRows-1 - lineNumber-numRows-1] += s[i]; 74 | array[2*numRows - lineNumber -2] += s[i]; 75 | } 76 | } 77 | 78 | return array.join(""); 79 | }; 80 | ``` 81 | -------------------------------------------------------------------------------- /questions/70md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 70. Climbing Stairs 2 | 3 | ##題目 4 | You are climbing a stair case. It takes n steps to reach to the top. 5 | 6 | Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? 7 | 8 | ##翻譯 9 | 你正在爬一個階梯。到頂端總共需走n階。 10 | 11 | 每次你都可以選擇爬1階或2階,問有幾種不同的方法可以爬到階梯頂端 12 | 13 | ##思路 14 | 15 | 1. n = 1, result = 1 16 | 2. n = 2, result = 1+1 (爬1階兩次 + 一次爬兩階) 17 | 3. n = 3, result = 1+2 (前面兩個case相加) 18 | 4. n = 4, result = 3+2 (前面兩個case相加) 19 | 5. 發現其實這題就是算費氏數列 20 | 21 | ##解題 22 | ``` 23 | /** 24 | * @param {number} n 25 | * @return {number} 26 | */ 27 | var climbStairs = function(n) { 28 | if(n<=1){ 29 | return 1; 30 | } 31 | 32 | var prev = 1; 33 | var cur = 1; 34 | // 費氏數列 f(n) = f(n-1) + f(n-2) 35 | for(var i = 2 ; i <=n ; i++){ 36 | var temp = cur; 37 | cur = cur + prev; 38 | prev = temp; 39 | } 40 | return cur; 41 | }; 42 | ``` -------------------------------------------------------------------------------- /questions/7md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 7. Reverse Integer 2 | 3 | ##題目 4 | Reverse digits of an integer. 5 | 6 | Example1: x = 123, return 321 7 | Example2: x = -123, return -321 8 | 9 | Have you thought about this? 10 | Here are some good questions to ask before coding. Bonus points for you if you have already thought through this! 11 | 12 | If the integer's last digit is 0, what should the output be? ie, cases such as 10, 100. 13 | 14 | Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the reverse of 1000000003 overflows. How should you handle such cases? 15 | 16 | For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows. 17 | 18 | ##翻譯 19 | 反轉一個int整數。 20 | 21 | x = 123 , return 321 22 | x = -123 , return -321 23 | 24 | 提示: 25 | 假如10,100反轉後會長怎樣。 26 | 27 | 你有注意到反轉後的數可能會超過Integer的範圍嗎,例如說1000000003反轉後就超過了32-bit的integer。這種情況要怎麼處理? 28 | 29 | 在這個問題中,超過integer只要回傳0就可以。 30 | 31 | ##思路 32 | 這是我一開始寫leetCode的解法,把數字轉成string後反轉,要額外處理的就是開頭是負數,-123反轉後變成321-,需把最後的負號搬到前面。 33 | 34 | 另外有不使用額外空間(ex. array,string etc.)的解法,請參考 [9. Palindrome Number](9md.md) 35 | ##解題 36 | ``` 37 | /** 38 | * @param {number} x 39 | * @return {number} 40 | */ 41 | var reverse = function(x) { 42 | var INT_MAX = Math.pow(2,31)-1; 43 | if(0 <= x && x < 10) return x; 44 | 45 | var nFlag = ""; 46 | // x to string 47 | var str = x.toString(); 48 | 49 | // reverse number string 50 | var rStr = nFlag + str.split("").reverse().join(""); 51 | 52 | // if x < 0, move '-' from rStr back to front 53 | if(rStr.indexOf('-') != -1){ 54 | rStr = '-' + rStr.replace('-',''); 55 | } 56 | 57 | var result = parseInt(rStr); 58 | 59 | if(result > INT_MAX || result < -(1+INT_MAX)) return 0; 60 | return result; 61 | }; 62 | ``` 63 | -------------------------------------------------------------------------------- /questions/83md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 83. Remove Duplicates from Sorted List 2 | 3 | ##題目 4 | Given a sorted linked list, delete all duplicates such that each element appear only once. 5 | 6 | For example, 7 | Given 1->1->2, return 1->2. 8 | Given 1->1->2->3->3, return 1->2->3. 9 | 10 | ##翻譯 11 | 改一個排序過的連結陣列,刪除重複的節點。 12 | 13 | 範例: 14 | [1,1,2] -> return [1,2] 15 | [1,1,2,3,3] -> return [1,2,3] 16 | 17 | ##思路 18 | 因為是排序過的,所以只要判斷後面的節點與當前的是否相同,如果後面的節點跟目前的相同,就跳過他。 19 | 20 | ##解題 21 | ``` 22 | /** 23 | * Definition for singly-linked list. 24 | * function ListNode(val) { 25 | * this.val = val; 26 | * this.next = null; 27 | * } 28 | */ 29 | /** 30 | * @param {ListNode} head 31 | * @return {ListNode} 32 | */ 33 | var deleteDuplicates = function(head) { 34 | if(head === null || head.next ===null) return head; 35 | var cur = head; 36 | 37 | while(cur.next !== null){ 38 | // 如果目前Node的值與下一個相同,跳過下一個 39 | if(cur.val == cur.next.val){ 40 | cur.next = cur.next.next; 41 | } else { 42 | cur = cur.next; 43 | } 44 | } 45 | return head; 46 | }; 47 | 48 | ``` -------------------------------------------------------------------------------- /questions/88md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 88. Merge Sorted Array 2 | 3 | ##題目 4 | Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. 5 | 6 | Note: 7 | You may assume that nums1 has enough space (size that is greater or equal to m + n) 8 | to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively 9 | 10 | ##翻譯 11 | 給兩個已經排序過的的整數陣列nums1與nums2,將nums2合併入nums1之中 12 | 13 | 注意: 14 | nums1會有有足夠的空間可以塞入兩個陣列(nums1.length = m+n),m為nums1的元素數量,n為nums2的元素數量 15 | 16 | 範例: 17 | nums1 = [1,1,2,4,6,null,null,null], m = 5, nums2 = [2,3,7], n = 3 18 | 合併後 nums1 = [1,1,2,2,3,4,6,7] 19 | 20 | ##思路 21 | 1. 這題可以分成兩個步驟就會變得很簡單,先把nums2的值放到nums1裡面 22 | ex. nums1 = [1,2,6,null,null] , nums2 = [4,5] --> [1,2,6,4,5] 23 | 2. 然後將nums1裡面的元素重新排序 [1,2,4,5,6] 24 | 25 | ##解題 26 | ``` 27 | /** 28 | * @param {number[]} nums1 29 | * @param {number} m 30 | * @param {number[]} nums2 31 | * @param {number} n 32 | * @return {void} Do not return anything, modify nums1 in-place instead. 33 | */ 34 | var merge = function(nums1, m, nums2, n) { 35 | 36 | var index = 0; 37 | //將nums2裡面的值放在nums1 38 | for(var i = m ; i < m+n ; i++){ 39 | nums1[i] = nums2[index]; 40 | index++; 41 | } 42 | 43 | //使用泡沫排序法重新排序 44 | for(var j = 0 ; j < nums1.length - 1 ; j++){ 45 | for(var k = j + 1 ; k < nums1.length ; k++){ 46 | if(nums1[j] > nums1[k]){ 47 | var temp = nums1[j]; 48 | nums1[j] = nums1[k]; 49 | nums1[k] = temp; 50 | } 51 | } 52 | } 53 | }; 54 | ``` 55 | -------------------------------------------------------------------------------- /questions/8md.md: -------------------------------------------------------------------------------- 1 | # LeetCode 8. String to Integer (atoi) 2 | 3 | ##題目 4 | Implement atoi to convert a string to an integer. 5 | 6 | Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases. 7 | 8 | Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front. 9 | 10 | Requirements for atoi: 11 | The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value. 12 | 13 | The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function. 14 | 15 | If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed. 16 | 17 | If no valid conversion could be performed, a zero value is returned. If the correct value is out of the range of representable values, INT_MAX (2147483647) or INT_MIN (-2147483648) is returned. 18 | 19 | ##翻譯 20 | 實作atoi將字串轉成int。 21 | 22 | 提示:小心仔細的考慮所有可能的輸入,如果你想挑戰自己,不要看下面的文字,直接想可能的輸入有哪些就可以開始寫了。 23 | 24 | 注意:這題目的輸入值有各種組合,你要先收集任何可能的輸入。 25 | 26 | atoi的需求: 27 | 首先輸入的開頭可能是一連串的空白,因此要先找到第一個非空白字元。然後從這個字元開始可能會有正負號在數字的前面,將這些字串轉換成數字。 28 | 29 | 如果在數字後面有出現其他非數字的符號,因為他們對值沒有影響,可以忽略這些符號。 30 | 31 | 如果第一個非空白字元不是一個合法的int整數,或者字串裡面都是空白字元,那也視為不合法的輸入。 32 | 33 | 不合法的輸入回傳0,如果轉換後的數字num > INT_MAX (2147483647) 回傳2147483647, num < INT_MIN (-2147483648) 回傳 -2147483648 34 | 35 | ##思路 36 | 這題看起來很複雜,通過率也低的很可怕,莫驚莫怕莫慌張,其實慢慢的一邊改一邊做,經過大量的Trial & Error,為拉低通過率做出一點貢獻,最後還是解得出來。 37 | 38 | 這邊當然不是來說一句Trial & Error,這題可以拆成以下幾個步驟一步一步解開: 39 | 1. 先把字串前面可能出現的空白字串都消除,找到第一個出現得+-符號或數字。 40 | 41 | 2. 如果剩下的開頭是+-符號,先用一個變數存放起來,然後把他截掉。 42 | 43 | 3. 如果輸入的字串是合法的,理論上現在開頭就應該只剩下數字,如果又出現+-號或其他字元,就可以判定為不合法字串。 44 | 45 | 4. 經過上面3取到最後都是數字,不過這沒影響。關,剩下的開頭肯定是數字了,這代表我們一定可以解析出一個整數出來,接下來將開頭到不是數字字元中間的數字字串取出來,當然也有可能一直到最後都是數字,不過這沒影響。 46 | 47 | 5. 結合剛才儲存的正負符號與上一個步驟拿到的數字字串後轉換成整數,這時候還要判斷整數是否超過int的最大值(2147483647)與最小值(-2147483648),超過的話上面題目已經說明過要怎麼處理,沒超過就直接回傳解析後的整數。 48 | 49 | ##解題 50 | ``` 51 | /** 52 | * @param {string} str 53 | * @return {number} 54 | */ 55 | var myAtoi = function(str) { 56 | var sign = '+'; //正負號 57 | var numReg = /^[0-9]/; 58 | 59 | //將前面的空白字串去掉, ex. "^^^^-122a" -> "-122a" (^代表空白) 60 | var i = 0; 61 | while(str.charAt(i)==' ' && i < str.length){ 62 | i++; 63 | } 64 | str = str.slice(i); 65 | 66 | 67 | //處理正負號, ex. "-122a" -> "122a" 68 | if(str.startsWith('+')){ 69 | str = str.slice(1); 70 | } else if(str.startsWith('-')){ 71 | str = str.slice(1); 72 | sign = '-'; 73 | } 74 | 75 | //處理後的字串不是數字開頭,代表字串不合法 76 | if(!numReg.test(str)) return 0; 77 | 78 | //出現不是數字的符號就中斷 79 | var j = 0; 80 | while(j < str.length && numReg.test(str[j])){ 81 | j++; 82 | }; 83 | // 截出開頭的數字字串, ex. '122a' -> '122' 84 | str = str.substr(0,j); 85 | 86 | //字串轉成int 87 | var value = parseInt(sign+str); 88 | if(value > 2147483647){ 89 | return 2147483647; 90 | } 91 | if(value < -2147483648){ 92 | return -2147483648; 93 | } 94 | return value; 95 | }; 96 | ``` 97 | -------------------------------------------------------------------------------- /questions/9md.md: -------------------------------------------------------------------------------- 1 | # LeetCodee 9. Palindrome Number 2 | ##題目 3 | Determine whether an integer is a palindrome. Do this without extra space. 4 | 5 | Some hints: 6 | Could negative integers be palindromes? (ie, -1) 7 | 8 | If you are thinking of converting the integer to string, note the restriction of using extra space. 9 | 10 | You could also try reversing an integer. However, if you have solved the problem "Reverse Integer", you know that the reversed integer might overflow. How would you handle such case? 11 | 12 | There is a more generic way of solving this problem. 13 | 14 | ##翻譯 15 | 判斷一個int整數是否是自己的迴文數,不能使用額外的空間來操作。 16 | 17 | 提示: 18 | 負整數會是自己的迴文數嗎(ex. -1) 19 | 20 | 如果你想用字串來解是不行的,因為不能使用額外的空間。 21 | 22 | 你也可以反轉整數,如果你之前已經做過[LeetCode 7. Reverse Integer](questions/7md.md),你會知道反轉後的數可能會超過integer的最大值。 23 | 24 | ##思路 25 | 不使用額外空間的意思,根據discuss裡面的討論,應該是不能用一個O(n)的額外空間(ex. array, string之類的),用一個O(1)的變數是可以的。 26 | 把傳入的x整個反轉後跟本來的x比較是否一致,這題還算簡單,直接看code。 27 | 28 | ##解題 29 | ``` 30 | /** 31 | * @param {number} x 32 | * @return {boolean} 33 | */ 34 | var isPalindrome = function(x) { 35 | // x < 0 or x > (2^32 - 1) , false; 36 | if(x < 0 || x > Math.pow(2,32)-1) return false; 37 | if(x < 10) return true; 38 | 39 | // keep x 40 | var num = x; 41 | 42 | // 先抓出最高位數,轉成個位數 43 | var recNum = x%10; 44 | x = parseInt(x/10); 45 | 46 | // 將recNum*10,再抓最高位數加到recNumb 47 | while(x != 0){ 48 | recNum = recNum*10; 49 | recNum = recNum + x%10; 50 | x = parseInt(x/10); 51 | } 52 | return recNum == num; 53 | }; 54 | ``` 55 | -------------------------------------------------------------------------------- /questions/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skyyen999/leetcodeWithJS/6b81e02561753b85de3b00ca5a760fe4e104955c/questions/README.md -------------------------------------------------------------------------------- /sortbyacceptance.md: -------------------------------------------------------------------------------- 1 | # 難易度排序 2 | | # | 題目 | 通過率 | 3 | |-----|-----------------------------------------------------------------------|-----| 4 | | 344 | [Reverse String](questions/344md.md) | 59% | 5 | | 292 | [Nim Game](questions/292md.md) | 54% | 6 | | 371 | [Sum of Two Integers](questions/371md.md) | 52% | 7 | | 258 | [Add Digits](questions/258md.md) | 49% | 8 | | 104 | [Maximum Depth of Binary Tree](questions/104md.md) | 49% | 9 | | 226 | [Invert Binary Tree](questions/226md.md) | 47% | 10 | | 283 | [Move Zeroes](questions/283md.md) | 46% | 11 | | 349 | [Intersection of Two Arrays](questions/349md.md) | 44% | 12 | | 237 | [Delete Node in a Linked List](questions/237md.md) | 44% | 13 | | 100 | [Same Tree](questions/100md.md) | 44% | 14 | | 171 | [Excel Sheet Column Number](questions/171md.md) | 43% | 15 | | 242 | [Valid Anagram](questions/242md.md) | 43% | 16 | | 169 | [Majority Element](questions/169md.md) | 43% | 17 | | 217 | [Contains Duplicate](questions/217md.md) | 42% | 18 | | 350 | [Intersection of Two Arrays II](questions/350md.md) | 42% | 19 | | 13 | [Roman to Integer](questions/13md.md) | 41% | 20 | | 206 | [Reverse Linked List](questions/206md.md) | 41% | 21 | | 231 | [Power of Two](questions/231md.md) | 38% | 22 | | 326 | [Power of Three](questions/326md.md) | 38% | 23 | | 191 | [Number of 1 Bits](questions/191md.md) | 38% | 24 | | 202 | [Happy Number](questions/202md.md) | 38% | 25 | | 263 | [Ugly Number](questions/263md.md) | 38% | 26 | | 83 | [Remove Duplicates from Sorted List](questions/83md.md) | 38% | 27 | | 235 | [Lowest Common Ancestor of a Binary Search Tree](questions/235md.md) | 38% | 28 | | 70 | [Climbing Stairs](questions/70md.md) | 37% | 29 | | 121 | [Best Time to Buy and Sell Stock](questions/121md.md) | 37% | 30 | | 141 | [Linked List Cycle](questions/141md.md) | 36% | 31 | | 21 | [Merge Two Sorted Lists](questions/21md.md) | 36% | 32 | | 345 | [Reverse Vowels of a String](questions/345md.md) | 36% | 33 | | 24 | [Swap Nodes in Pairs](questions/24md.md) | 36% | 34 | | 198 | [House Robber](questions/198md.md) | 36% | 35 | | 342 | [Power of Four](questions/342md.md) | 36% | 36 | | 107 | [Binary Tree Level Order Traversal II](questions/107md.md) | 35% | 37 | | 27 | [Remove Element](questions/27md.md) | 35% | 38 | | 101 | [Symmetric Tree](questions/101md.md) | 35% | 39 | | 66 | [Plus One](questions/66md.md) | 35% | 40 | | 110 | [Balanced Binary Tree](questions/110md.md) | 35% | 41 | | 118 | [Pascal's Triangle](questions/118md.md) | 35% | 42 | | 232 | [Implement Queue using Stacks](questions/232md.md) | 34% | 43 | | 26 | [Remove Duplicates from Sorted Array](questions/26md.md) | 34% | 44 | | 102 | [Binary Tree Level Order Traversal](questions/102md.md) | 34% | 45 | | 172 | [Factorial Trailing Zeroes](questions/172md.md) | 34% | 46 | | 119 | [Pascal's Triangle II](questions/119md.md) | 33% | 47 | | 9 | [Palindrome Number](questions/9md.md) | 33% | 48 | | 36 | [Valid Sudoku](questions/36md.md) | 32% | 49 | | 112 | [Path Sum](questions/112md.md) | 32% | 50 | | 374 | [Guess Number Higher or Lower](questions/374md.md) | 31% | 51 | | 299 | [Bulls and Cows](questions/299md.md) | 31% | 52 | | 111 | [Minimum Depth of Binary Tree](questions/111md.md) | 31% | 53 | | 205 | [Isomorphic Strings](questions/205md.md) | 31% | 54 | | 225 | [Implement Stack using Queues](questions/225md.md) | 31% | 55 | | 223 | [Rectangle Area](questions/223md.md) | 31% | 56 | | 257 | [Binary Tree Paths](questions/257md.md) | 31% | 57 | | 160 | [Intersection of Two Linked Lists](questions/160md.md) | 31% | 58 | | 219 | [Contains Duplicate II](questions/219md.md) | 31% | 59 | | 88 | [Merge Sorted Array](questions/88md.md) | 31% | 60 | | 19 | [Remove Nth Node From End of List](questions/19md.md) | 31% | 61 | | 290 | [Word Pattern](questions/290md.md) | 31% | 62 | | 38 | [Count and Say](questions/38md.md) | 30% | 63 | | 20 | [Valid Parentheses](questions/20md.md) | 30% | 64 | | 58 | [Length of Last Word](questions/58md.md) | 30% | 65 | | 203 | [Remove Linked List Elements](questions/203md.md) | 30% | 66 | | 234 | [Palindrome Linked List](questions/234md.md) | 30% | 67 | | 190 | [Reverse Bits](questions/190md.md) | 29% | 68 | | 14 | [Longest Common Prefix](questions/14md.md) | 29% | 69 | | 67 | [Add Binary](questions/67md.md) | 29% | 70 | | 28 | [Implement strStr()](questions/28md.md) | 26% | 71 | | 303 | [Range Sum Query - Immutable](questions/303md.md) | 26% | 72 | | 204 | [Count Primes](questions/204md.md) | 25% | 73 | | 1 | [Two Sum](questions/1md.md) | 25% | 74 | | 6 | [ZigZag Conversion](questions/6md.md) | 25% | 75 | | 125 | [Valid Palindrome](questions/125md.md) | 24% | 76 | | 7 | [Reverse Integer](questions/7md.md) | 24% | 77 | | 155 | [Min Stack](questions/155md.md) | 24% | 78 | | 278 | [First Bad Version](questions/278md.md) | 23% | 79 | | 168 | [Excel Sheet Column Title](questions/168md.md) | 23% | 80 | | 189 | [Rotate Array](questions/189md.md) | 22% | 81 | | 165 | [Compare Version Numbers](questions/165md.md) | 18% | 82 | | 8 | [String to Integer (atoi)](questions/8md.md) | 14% | -------------------------------------------------------------------------------- /sortbynumber.md: -------------------------------------------------------------------------------- 1 | # 題號排序 2 | | # | 題目 | 通過率 | 3 | |-----|-----------------------------------------------------------------------|-----| 4 | | 1 | [Two Sum](questions/1md.md) | 25% | 5 | | 6 | [ZigZag Conversion](questions/6md.md) | 25% | 6 | | 7 | [Reverse Integer](questions/7md.md) | 24% | 7 | | 8 | [String to Integer (atoi)](questions/8md.md) | 14% | 8 | | 9 | [Palindrome Number](questions/9md.md) | 33% | 9 | | 13 | [Roman to Integer](questions/13md.md) | 41% | 10 | | 14 | [Longest Common Prefix](questions/14md.md) | 29% | 11 | | 19 | [Remove Nth Node From End of List](questions/19md.md) | 31% | 12 | | 20 | [Valid Parentheses](questions/20md.md) | 30% | 13 | | 21 | [Merge Two Sorted Lists](questions/21md.md) | 36% | 14 | | 24 | [Swap Nodes in Pairs](questions/24md.md) | 36% | 15 | | 26 | [Remove Duplicates from Sorted Array](questions/26md.md) | 34% | 16 | | 27 | [Remove Element](questions/27md.md) | 35% | 17 | | 28 | [Implement strStr()](questions/28md.md) | 26% | 18 | | 36 | [Valid Sudoku](questions/36md.md) | 32% | 19 | | 38 | [Count and Say](questions/38md.md) | 30% | 20 | | 58 | [Length of Last Word](questions/58md.md) | 30% | 21 | | 66 | [Plus One](questions/66md.md) | 35% | 22 | | 67 | [Add Binary](questions/67md.md) | 29% | 23 | | 70 | [Climbing Stairs](questions/70md.md) | 37% | 24 | | 83 | [Remove Duplicates from Sorted List](questions/83md.md) | 38% | 25 | | 88 | [Merge Sorted Array](questions/88md.md) | 31% | 26 | | 100 | [Same Tree](questions/100md.md) | 44% | 27 | | 101 | [Symmetric Tree](questions/101md.md) | 35% | 28 | | 102 | [Binary Tree Level Order Traversal](questions/102md.md) | 34% | 29 | | 104 | [Maximum Depth of Binary Tree](questions/104md.md) | 49% | 30 | | 107 | [Binary Tree Level Order Traversal II](questions/107md.md) | 35% | 31 | | 110 | [Balanced Binary Tree](questions/110md.md) | 35% | 32 | | 111 | [Minimum Depth of Binary Tree](questions/111md.md) | 31% | 33 | | 112 | [Path Sum](questions/112md.md) | 32% | 34 | | 118 | [Pascal's Triangle](questions/118md.md) | 35% | 35 | | 119 | [Pascal's Triangle II](questions/119md.md) | 33% | 36 | | 121 | [Best Time to Buy and Sell Stock](questions/121md.md) | 37% | 37 | | 125 | [Valid Palindrome](questions/125md.md) | 24% | 38 | | 141 | [Linked List Cycle](questions/141md.md) | 36% | 39 | | 155 | [Min Stack](questions/155md.md) | 24% | 40 | | 160 | [Intersection of Two Linked Lists](questions/160md.md) | 31% | 41 | | 165 | [Compare Version Numbers](questions/165md.md) | 18% | 42 | | 168 | [Excel Sheet Column Title](questions/168md.md) | 23% | 43 | | 169 | [Majority Element](questions/169md.md) | 43% | 44 | | 171 | [Excel Sheet Column Number](questions/171md.md) | 43% | 45 | | 172 | [Factorial Trailing Zeroes](questions/172md.md) | 34% | 46 | | 189 | [Rotate Array](questions/189md.md) | 22% | 47 | | 190 | [Reverse Bits](questions/190md.md) | 29% | 48 | | 191 | [Number of 1 Bits](questions/191md.md) | 38% | 49 | | 198 | [House Robber](questions/198md.md) | 36% | 50 | | 202 | [Happy Number](questions/202md.md) | 38% | 51 | | 203 | [Remove Linked List Elements](questions/203md.md) | 30% | 52 | | 204 | [Count Primes](questions/204md.md) | 25% | 53 | | 205 | [Isomorphic Strings](questions/205md.md) | 31% | 54 | | 206 | [Reverse Linked List](questions/206md.md) | 41% | 55 | | 217 | [Contains Duplicate](questions/217md.md) | 42% | 56 | | 219 | [Contains Duplicate II](questions/219md.md) | 31% | 57 | | 223 | [Rectangle Area](questions/223md.md) | 31% | 58 | | 225 | [Implement Stack using Queues](questions/225md.md) | 31% | 59 | | 226 | [Invert Binary Tree](questions/226md.md) | 47% | 60 | | 231 | [Power of Two](questions/231md.md) | 38% | 61 | | 232 | [Implement Queue using Stacks](questions/232md.md) | 34% | 62 | | 234 | [Palindrome Linked List](questions/234md.md) | 30% | 63 | | 235 | [Lowest Common Ancestor of a Binary Search Tree](questions/235md.md) | 38% | 64 | | 237 | [Delete Node in a Linked List](questions/237md.md) | 44% | 65 | | 242 | [Valid Anagram](questions/242md.md) | 43% | 66 | | 257 | [Binary Tree Paths](questions/257md.md) | 31% | 67 | | 258 | [Add Digits](questions/258md.md) | 49% | 68 | | 263 | [Ugly Number](questions/263md.md) | 38% | 69 | | 278 | [First Bad Version](questions/278md.md) | 23% | 70 | | 283 | [Move Zeroes](questions/283md.md) | 46% | 71 | | 290 | [Word Pattern](questions/290md.md) | 31% | 72 | | 292 | [Nim Game](questions/292md.md) | 54% | 73 | | 299 | [Bulls and Cows](questions/299md.md) | 31% | 74 | | 303 | [Range Sum Query - Immutable](questions/303md.md) | 26% | 75 | | 326 | [Power of Three](questions/326md.md) | 38% | 76 | | 342 | [Power of Four](questions/342md.md) | 36% | 77 | | 344 | [Reverse String](questions/344md.md) | 59% | 78 | | 345 | [Reverse Vowels of a String](questions/345md.md) | 36% | 79 | | 349 | [Intersection of Two Arrays](questions/349md.md) | 44% | 80 | | 350 | [Intersection of Two Arrays II](questions/350md.md) | 42% | 81 | | 371 | [Sum of Two Integers](questions/371md.md) | 52% | 82 | | 374 | [Guess Number Higher or Lower](questions/374md.md) | 31% | -------------------------------------------------------------------------------- /string.md: -------------------------------------------------------------------------------- 1 | # 字串String 2 | 3 | -------------------------------------------------------------------------------- /styles/print.css: -------------------------------------------------------------------------------- 1 | /* CSS for print */ 2 | -------------------------------------------------------------------------------- /styles/website.css: -------------------------------------------------------------------------------- 1 | /* CSS for website */ 2 | --------------------------------------------------------------------------------