├── .gitignore ├── Algorithms ├── 001两数之和two-sum │ └── two-sum.js ├── 003无重复字符的最长子串longest-substring-without-repeating-characters │ └── longest-substring-without-repeating-characters.js ├── 005最长回文子串longest-palindromic-substring │ └── longest-palindromic-substring.js ├── 007反转整数reverse-integer │ └── reverse-integer.js ├── 008字符串转整数 (atoi)string-to-integer-atoi │ └── string-to-integer-atoi.js ├── 009回文数palindrome-number │ └── palindrome-number.js ├── 014最长公共前缀longest-common-prefix │ └── longest-common-prefix.js ├── 020有效的括号valid-parentheses │ └── valid-parentheses.js ├── 021合并两个有序链表merge-two-sorted-lists │ └── merge-two-sorted-lists.js ├── 026删除排序数组中的重复项remove-duplicates-from-sorted-array │ └── remove-duplicates-from-sorted-array.js ├── 027移除元素remove-element │ └── remove-element.js ├── 028实现strStr()implement-strstr │ └── implement-strstr.js ├── 035搜索插入位置search-insert-position │ └── search-insert-position.js ├── 036有效的数独valid-sudoku │ └── valid-sudoku.js ├── 049字母异位词分组group-anagrams │ └── group-anagrams.js ├── 053最大子序和maximum-subarray │ └── maximum-subarray.js ├── 056合并区间merge-intervals │ └── merge-intervals.js ├── 057插入区间insert-interval │ └── insert-interval.js ├── 058最后一个单词的长度length-of-last-word │ └── length-of-last-word.js ├── 065有效数字valid-number │ └── valid-number.js ├── 069x 的平方根sqrtx │ └── sqrtx.js ├── 070爬楼梯climbing-stairs │ └── climbing-stairs.js ├── 088合并两个有序数组merge-sorted-array │ └── merge-sorted-array.js ├── 094二叉树的中序遍历binary-tree-inorder-traversal │ └── binary-tree-inorder-traversal.js ├── 096不同的二叉搜索树unique-binary-search-trees │ └── unique-binary-search-trees.js ├── 098验证二叉搜索树validate-binary-search-tree │ └── validate-binary-search-tree.js ├── 099恢复二叉搜索树recover-binary-search-tree │ └── recover-binary-search-tree.js ├── 100相同的树same-tree │ └── same-tree.js ├── 101对称二叉树symmetric-tree │ └── symmetric-tree.js ├── 102二叉树的层次遍历binary-tree-level-order-traversal │ └── binary-tree-level-order-traversal.js ├── 103二叉树的锯齿形层次遍历binary-tree-zigzag-level-order-traversal │ └── binary-tree-zigzag-level-order-traversal.js ├── 104二叉树的最大深度maximum-depth-of-binary-tree │ └── maximum-depth-of-binary-tree.js ├── 105从前序与中序遍历序列构造二叉树construct-binary-tree-from-preorder-and-inorder-traversal │ └── construct-binary-tree-from-preorder-and-inorder-traversal.js ├── 106从中序与后序遍历序列构造二叉树construct-binary-tree-from-inorder-and-postorder-traversal │ └── construct-binary-tree-from-inorder-and-postorder-traversal.js ├── 108将有序数组转换为二叉搜索树convert-sorted-array-to-binary-search-tree │ └── convert-sorted-array-to-binary-search-tree.js ├── 109有序链表转换二叉搜索树convert-sorted-list-to-binary-search-tree │ └── convert-sorted-list-to-binary-search-tree.js ├── 110平衡二叉树balanced-binary-tree │ └── balanced-binary-tree.js ├── 111二叉树的最小深度minimum-depth-of-binary-tree │ └── minimum-depth-of-binary-tree.js ├── 112路径总和path-sum │ └── path-sum.js ├── 113路径总和 IIpath-sum-ii │ └── path-sum-ii.js ├── 116填充同一层的兄弟节点populating-next-right-pointers-in-each-node │ └── populating-next-right-pointers-in-each-node.js ├── 117填充同一层的兄弟节点 IIpopulating-next-right-pointers-in-each-node-ii │ └── populating-next-right-pointers-in-each-node-ii.js ├── 118杨辉三角pascals-triangle │ └── pascals-triangle.js ├── 119杨辉三角 IIpascals-triangle-ii │ └── pascals-triangle-ii.js ├── 121买卖股票的最佳时机best-time-to-buy-and-sell-stock │ └── best-time-to-buy-and-sell-stock.js ├── 122买卖股票的最佳时机 IIbest-time-to-buy-and-sell-stock-ii │ └── best-time-to-buy-and-sell-stock-ii.js ├── 125验证回文串valid-palindrome │ └── valid-palindrome.js ├── 128最长连续序列longest-consecutive-sequence │ └── longest-consecutive-sequence.js ├── 129求根到叶子节点数字之和sum-root-to-leaf-numbers │ └── sum-root-to-leaf-numbers.js ├── 136只出现一次的数字single-number │ └── single-number.js ├── 141环形链表linked-list-cycle │ └── linked-list-cycle.js ├── 144二叉树的前序遍历binary-tree-preorder-traversal │ └── binary-tree-preorder-traversal.js ├── 145二叉树的后序遍历binary-tree-postorder-traversal │ └── binary-tree-postorder-traversal.js ├── 148排序链表sort-list │ └── sort-list.js ├── 167两数之和 II - 输入有序数组two-sum-ii-input-array-is-sorted │ └── two-sum-ii-input-array-is-sorted.js ├── 168Excel表列名称excel-sheet-column-title │ └── excel-sheet-column-title.js ├── 169求众数majority-element │ └── majority-element.js ├── 171Excel表列序号excel-sheet-column-number │ └── excel-sheet-column-number.js ├── 173二叉搜索树迭代器binary-search-tree-iterator │ └── binary-search-tree-iterator.js ├── 179最大数largest-number │ └── largest-number.js ├── 198打家劫舍house-robber │ └── house-robber.js ├── 199二叉树的右视图binary-tree-right-side-view │ └── binary-tree-right-side-view.js ├── 202快乐数happy-number │ └── happy-number.js ├── 205同构字符串isomorphic-strings │ └── isomorphic-strings.js ├── 217存在重复元素contains-duplicate │ └── contains-duplicate.js ├── 219存在重复元素 IIcontains-duplicate-ii │ └── contains-duplicate-ii.js ├── 220存在重复元素 IIIcontains-duplicate-iii │ └── contains-duplicate-iii.js ├── 226翻转二叉树invert-binary-tree │ └── invert-binary-tree.js ├── 229求众数 IImajority-element-ii │ └── majority-element-ii.js ├── 230二叉搜索树中第K小的元素kth-smallest-element-in-a-bst │ └── kth-smallest-element-in-a-bst.js ├── 2312的幂power-of-two │ └── power-of-two.js ├── 235二叉搜索树的最近公共祖先lowest-common-ancestor-of-a-binary-search-tree │ └── lowest-common-ancestor-of-a-binary-search-tree.js ├── 236二叉树的最近公共祖先lowest-common-ancestor-of-a-binary-tree │ └── lowest-common-ancestor-of-a-binary-tree.js ├── 242有效的字母异位词valid-anagram │ └── valid-anagram.js ├── 257二叉树的所有路径binary-tree-paths │ └── binary-tree-paths.js ├── 260只出现一次的数字 IIIsingle-number-iii │ └── single-number-iii.js ├── 268缺失数字missing-number │ └── missing-number.js ├── 283移动零move-zeroes │ └── move-zeroes.js ├── 290单词模式word-pattern │ └── word-pattern.js ├── 292Nim游戏nim-game │ └── nim-game.js ├── 297二叉树的序列化与反序列化serialize-and-deserialize-binary-tree │ └── serialize-and-deserialize-binary-tree.js ├── 303区域和检索 - 数组不可变range-sum-query-immutable │ └── range-sum-query-immutable.js ├── 3263的幂power-of-three │ └── power-of-three.js ├── 3424的幂power-of-four │ └── power-of-four.js ├── 344反转字符串reverse-string │ └── reverse-string.js ├── 345反转字符串中的元音字母reverse-vowels-of-a-string │ └── reverse-vowels-of-a-string.js ├── 349两个数组的交集intersection-of-two-arrays │ └── intersection-of-two-arrays.js ├── 350两个数组的交集 IIintersection-of-two-arrays-ii │ └── intersection-of-two-arrays-ii.js ├── 367有效的完全平方数valid-perfect-square │ └── valid-perfect-square.js ├── 371两整数之和sum-of-two-integers │ └── sum-of-two-integers.js ├── 387字符串中的第一个唯一字符first-unique-character-in-a-string │ └── first-unique-character-in-a-string.js ├── 389找不同find-the-difference │ └── find-the-difference.js ├── 404左叶子之和sum-of-left-leaves │ └── sum-of-left-leaves.js ├── 409最长回文串longest-palindrome │ └── longest-palindrome.js ├── 434字符串中的单词数number-of-segments-in-a-string │ └── number-of-segments-in-a-string.js ├── 437路径总和 IIIpath-sum-iii │ └── path-sum-iii.js ├── 442数组中重复的数据find-all-duplicates-in-an-array │ └── find-all-duplicates-in-an-array.js ├── 448找到所有数组中消失的数字find-all-numbers-disappeared-in-an-array │ └── find-all-numbers-disappeared-in-an-array.js ├── 450删除二叉搜索树中的节点delete-node-in-a-bst │ └── delete-node-in-a-bst.js ├── 451根据字符出现频率排序sort-characters-by-frequency │ └── sort-characters-by-frequency.js ├── 459重复的子字符串repeated-substring-pattern │ └── repeated-substring-pattern.js ├── 485最大连续1的个数max-consecutive-ones │ └── max-consecutive-ones.js ├── 500键盘行keyboard-row │ └── keyboard-row.js ├── 507完美数perfect-number │ └── perfect-number.js ├── 513找树左下角的值find-bottom-left-tree-value │ └── find-bottom-left-tree-value.js ├── 515在每个树行中找最大值find-largest-value-in-each-tree-row │ └── find-largest-value-in-each-tree-row.js ├── 520检测大写字母detect-capital │ └── detect-capital.js ├── 543二叉树的直径diameter-of-binary-tree │ └── diameter-of-binary-tree.js ├── 557反转字符串中的单词 IIIreverse-words-in-a-string-iii │ └── reverse-words-in-a-string-iii.js ├── 561数组拆分 Iarray-partition-i │ └── array-partition-i.js ├── 563二叉树的坡度binary-tree-tilt │ └── binary-tree-tilt.js ├── 572另一个树的子树subtree-of-another-tree │ └── subtree-of-another-tree.js ├── 606根据二叉树创建字符串construct-string-from-binary-tree │ └── construct-string-from-binary-tree.js ├── 617合并二叉树merge-two-binary-trees │ └── merge-two-binary-trees.js ├── 623在二叉树中增加一行add-one-row-to-tree │ └── add-one-row-to-tree.js ├── 628三个数的最大乘积maximum-product-of-three-numbers │ └── maximum-product-of-three-numbers.js ├── 633平方数之和sum-of-square-numbers │ └── sum-of-square-numbers.js ├── 637二叉树的层平均值average-of-levels-in-binary-tree │ └── average-of-levels-in-binary-tree.js ├── 647回文子串palindromic-substrings │ └── palindromic-substrings.js ├── 652寻找重复的子树find-duplicate-subtrees │ └── find-duplicate-subtrees.js ├── 653两数之和 IV - 输入 BSTtwo-sum-iv-input-is-a-bst │ └── two-sum-iv-input-is-a-bst.js ├── 654最大二叉树maximum-binary-tree │ └── maximum-binary-tree.js ├── 657判断路线成圈judge-route-circle │ └── judge-route-circle.js ├── 662二叉树最大宽度maximum-width-of-binary-tree │ └── maximum-width-of-binary-tree.js ├── 669修剪二叉搜索树trim-a-binary-search-tree │ └── trim-a-binary-search-tree.js ├── 671二叉树中第二小的节点second-minimum-node-in-a-binary-tree │ └── second-minimum-node-in-a-binary-tree.js ├── 687最长同值路径longest-univalue-path │ └── longest-univalue-path.js ├── 709转换成小写字母to-lower-case │ └── to-lower-case.js ├── 720词典中最长的单词longest-word-in-dictionary │ └── longest-word-in-dictionary.js ├── 728自除数self-dividing-numbers │ └── self-dividing-numbers.js ├── 744寻找比目标字母大的最小字母find-smallest-letter-greater-than-target │ └── find-smallest-letter-greater-than-target.js ├── 746使用最小花费爬楼梯min-cost-climbing-stairs │ └── min-cost-climbing-stairs.js ├── 771宝石与石头jewels-and-stones │ └── jewels-and-stones.js ├── 784字母大小写全排列letter-case-permutation │ └── letter-case-permutation.js ├── 788旋转数字rotated-digits │ └── rotated-digits.js ├── 791自定义字符串排序custom-sort-string │ └── custom-sort-string.js ├── 796旋转字符串rotate-string │ └── rotate-string.js ├── 806写字符串需要的行数number-of-lines-to-write-string │ └── number-of-lines-to-write-string.js ├── 811子域名访问计数subdomain-visit-count │ └── subdomain-visit-count.js ├── 814二叉树剪枝binary-tree-pruning │ └── binary-tree-pruning.js ├── 819最常见的单词most-common-word │ └── most-common-word.js ├── 832翻转图像flipping-an-image │ └── flipping-an-image.js └── 844比较含退格的字符串backspace-string-compare │ └── backspace-string-compare.js ├── README.md ├── batch_files.js ├── package-lock.json ├── package.json ├── spider.js └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | example1.png 23 | example.png 24 | page.png 25 | config.js 26 | example.png 27 | -------------------------------------------------------------------------------- /Algorithms/001两数之和two-sum/two-sum.js: -------------------------------------------------------------------------------- 1 | /* leetcode 001两数之和two-sum JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @param {number} target * @return {number[]} */ 4 | var twoSum = function(nums, target) { 5 | var i = 0, 6 | j, len = nums.length, 7 | item, inItem; 8 | for (i; i < len; i++) { 9 | item = nums[i]; 10 | for (j = i + 1; j < len; j++) { 11 | inItem = nums[j]; 12 | if (item + inItem == target) { 13 | return [i, j]; 14 | } 15 | } 16 | } 17 | }; -------------------------------------------------------------------------------- /Algorithms/003无重复字符的最长子串longest-substring-without-repeating-characters/longest-substring-without-repeating-characters.js: -------------------------------------------------------------------------------- 1 | /* leetcode 003无重复字符的最长子串longest-substring-without-repeating-characters JavaScript实现 */ 2 | 3 | /** * @param {string} s * @return {number} */ 4 | var lengthOfLongestSubstring = function(s) { 5 | if (s.length == 0) { 6 | return 0; 7 | } 8 | var sArr = s.split(''); 9 | var resArr = [sArr[0]]; 10 | var res = 1; 11 | var item; 12 | for (var i = 0; i < s.length; i++) { 13 | item = sArr[i]; 14 | var indexOf = resArr.indexOf(item); /* 如果下一个字符包含在目前 的字符串中,就截取已有字符串中,从该字符串后面的。*/ 15 | if (indexOf > -1) { 16 | resArr = resArr.splice(indexOf + 1); 17 | } 18 | resArr.push(item); 19 | res = resArr.length > res ? resArr.length : res; 20 | } 21 | return res; 22 | }; -------------------------------------------------------------------------------- /Algorithms/005最长回文子串longest-palindromic-substring/longest-palindromic-substring.js: -------------------------------------------------------------------------------- 1 | /* leetcode 005最长回文子串longest-palindromic-substring JavaScript实现 */ 2 | 3 | /** * @param {string} s * @return {string} */ 4 | var longestPalindrome = function(s) { 5 | if (s.length == 0) { 6 | return ''; 7 | } 8 | var sArr = s.split(''); 9 | var res = ''; 10 | var item; /* 一种情况是以自身为中轴,往两边找。 如aba.*/ /* 二种情况是有很多重复的自身。以这些重复的自身为中轴。*/ /* 首先计算出中轴的起止位。*/ 11 | for (var i = 0; i < s.length; i++) { 12 | item = sArr[i]; 13 | var subS = item; 14 | var beforeIndex = 1; 15 | while (true) { 16 | if (sArr[i - beforeIndex] == item) { 17 | beforeIndex++; 18 | subS += item; 19 | } else { 20 | break; 21 | } 22 | } 23 | var afterIndex = 1; 24 | while (true) { 25 | if (sArr[i + afterIndex] == item) { 26 | afterIndex++; 27 | subS += item; 28 | } else { 29 | break; 30 | } 31 | } 32 | var inteval = 1; 33 | while (true) { 34 | var before = sArr[i - beforeIndex + 1 - inteval]; 35 | var after = sArr[i + afterIndex - 1 + inteval]; /* before,after这个思路还是有点不对。abbc这*/ 36 | if (before && after && before == after) { 37 | inteval++; 38 | subS = before + subS + after; 39 | } else { 40 | break; 41 | } 42 | } 43 | if (subS.length > res.length) { 44 | res = subS; 45 | } 46 | } 47 | return res; 48 | }; -------------------------------------------------------------------------------- /Algorithms/007反转整数reverse-integer/reverse-integer.js: -------------------------------------------------------------------------------- 1 | /* leetcode 007反转整数reverse-integer JavaScript实现 */ 2 | 3 | /** * @param {number} x * @return {number} */ 4 | var reverse = function(x) { 5 | var sign = ''; 6 | var str = x.toString(); 7 | if (x >= 0) { 8 | sign = ''; 9 | } else { 10 | sign = '-'; 11 | str = str.split('-')[1]; 12 | } 13 | var revStr = str.split('').reverse().join(''); 14 | var resStr = sign + revStr; 15 | var resNum = parseInt(resStr); 16 | if (-Math.pow(2, 31) > resNum || Math.pow(2, 31) - 1 < resNum) { 17 | return 0; 18 | } 19 | return resNum; 20 | }; -------------------------------------------------------------------------------- /Algorithms/008字符串转整数 (atoi)string-to-integer-atoi/string-to-integer-atoi.js: -------------------------------------------------------------------------------- 1 | /* leetcode 008字符串转整数 (atoi)string-to-integer-atoi JavaScript实现 */ 2 | 3 | /** * @param {string} str * @return {number} */ 4 | var myAtoi = function(str) { 5 | str = str.trim(); 6 | var sign = ''; /* 如果有正负号*/ 7 | var macthSign = str.match(/^[+-]/); 8 | if (macthSign) { 9 | sign = macthSign[0]; 10 | str = str.slice(1); 11 | } /* 数字,+-号开始。*/ 12 | var reg = /^[0-9]+/ 13 | var matchNum = str.match(reg); 14 | if (matchNum) { 15 | var numStr = matchNum[0]; 16 | var num = parseInt(sign + numStr, 10); 17 | if (-Math.pow(2, 31) > num) { 18 | return -Math.pow(2, 31); 19 | } 20 | if (Math.pow(2, 31) - 1 < num) { 21 | return Math.pow(2, 31) - 1; 22 | } 23 | return num; 24 | } else { 25 | return 0; 26 | } 27 | }; -------------------------------------------------------------------------------- /Algorithms/009回文数palindrome-number/palindrome-number.js: -------------------------------------------------------------------------------- 1 | /* leetcode 009回文数palindrome-number JavaScript实现 */ 2 | 3 | /** * @param {number} x * @return {boolean} */ 4 | var isPalindrome = function(x) { 5 | return x.toString().split('').reverse().join('') === x.toString() 6 | }; -------------------------------------------------------------------------------- /Algorithms/014最长公共前缀longest-common-prefix/longest-common-prefix.js: -------------------------------------------------------------------------------- 1 | /* leetcode 014最长公共前缀longest-common-prefix JavaScript实现 */ 2 | 3 | /** * @param {string[]} strs * @return {string} */ 4 | var longestCommonPrefix = function(strs) { 5 | if (strs.length == 0) { 6 | return ''; 7 | } /* 第一个全部看成前缀*/ 8 | var pre = strs[0].split(''); 9 | strs.forEach(function(v, i) { 10 | if (i == 0) { 11 | return; 12 | } 13 | var j = 0; 14 | var vArr = v.split(''); 15 | while (j <= vArr.length && j <= pre.length) { 16 | if (vArr[j] != pre[j]) { 17 | pre = pre.slice(0, j); 18 | break; 19 | } 20 | j++; 21 | } 22 | }); 23 | return pre.join(''); 24 | }; -------------------------------------------------------------------------------- /Algorithms/020有效的括号valid-parentheses/valid-parentheses.js: -------------------------------------------------------------------------------- 1 | /* leetcode 020有效的括号valid-parentheses JavaScript实现 */ 2 | 3 | /** * @param {string} s * @return {boolean} */ /* 不断替换掉里面的(){}[],最后如果还有剩下的,说明不对。*/ 4 | var isValid = function(s) { 5 | var splitReg = /(\(\))|(\[\])|(\{\})/g; 6 | while (s.match(splitReg)) { 7 | s = s.replace(splitReg, '') 8 | } 9 | return s === ''; 10 | }; -------------------------------------------------------------------------------- /Algorithms/021合并两个有序链表merge-two-sorted-lists/merge-two-sorted-lists.js: -------------------------------------------------------------------------------- 1 | /* leetcode 21.合并两个有序链表 JavaScript实现 */ 2 | 3 | /** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */ 4 | /** * @param {ListNode} l1 * @param {ListNode} l2 * @return {ListNode} */ 5 | var mergeTwoLists = function(l1, l2) { 6 | var l1Next = l1; 7 | var l2Next = l2; 8 | var res; 9 | var resNext; 10 | if (!l1) { 11 | return l2; 12 | } 13 | if (!l2) { 14 | return l1; 15 | } 16 | while (l1Next && l2Next) { 17 | var val1 = l1Next.val; 18 | var val2 = l2Next.val; 19 | if (val1 <= val2) { 20 | if (!res) { 21 | res = new ListNode(val1); 22 | resNext = res; 23 | } else { /* 给next赋值*/ 24 | resNext.next = new ListNode(val1); /* 移动索引。*/ 25 | resNext = resNext.next; 26 | } 27 | l1Next = l1Next.next; 28 | } else { 29 | if (!res) { 30 | res = new ListNode(val2); 31 | resNext = res; 32 | } else { 33 | resNext.next = new ListNode(val2); 34 | resNext = resNext.next; 35 | } 36 | l2Next = l2Next.next; 37 | } 38 | } /* 剩下的直接加后面*/ 39 | if (l1Next) { 40 | resNext.next = l1Next; 41 | } 42 | if (l2Next) { 43 | resNext.next = l2Next; 44 | } 45 | return res; 46 | }; -------------------------------------------------------------------------------- /Algorithms/026删除排序数组中的重复项remove-duplicates-from-sorted-array/remove-duplicates-from-sorted-array.js: -------------------------------------------------------------------------------- 1 | /* leetcode 026删除排序数组中的重复项remove-duplicates-from-sorted-array JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @return {number} */ 4 | var removeDuplicates = function(nums) { /* 已成功的,放到一个字符串中。给每一项加上前后缀确保完全匹配*/ /* 跟成功的匹配上了就删除。说明重复。*/ 5 | var okStr = ''; 6 | for (var i = 0; i < nums.length;) { 7 | item = nums[i]; 8 | if (okStr.match('_' + item + '_')) { 9 | nums.splice(i, 1); 10 | } else { 11 | okStr = okStr + '_' + item + '_'; 12 | i++; 13 | } 14 | } 15 | return nums.length; 16 | }; -------------------------------------------------------------------------------- /Algorithms/027移除元素remove-element/remove-element.js: -------------------------------------------------------------------------------- 1 | /* leetcode 027移除元素remove-element JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @param {number} val * @return {number} */ 4 | var removeElement = function(nums, val) { 5 | for (var i = 0; i < nums.length;) { 6 | item = nums[i]; 7 | if (item == val) { 8 | nums.splice(i, 1); 9 | } else { 10 | i++; 11 | } 12 | } 13 | return nums.length; 14 | }; -------------------------------------------------------------------------------- /Algorithms/028实现strStr()implement-strstr/implement-strstr.js: -------------------------------------------------------------------------------- 1 | /* leetcode 028实现strStr()implement-strstr JavaScript实现 */ 2 | 3 | /** * @param {string} haystack * @param {string} needle * @return {number} */ 4 | var strStr = function(haystack, needle) { 5 | if (needle == '') { 6 | return 0; 7 | } 8 | var reg = new RegExp(needle); 9 | var match = haystack.match(reg); 10 | if (!match) { 11 | return -1; 12 | } 13 | return match.index; 14 | }; -------------------------------------------------------------------------------- /Algorithms/035搜索插入位置search-insert-position/search-insert-position.js: -------------------------------------------------------------------------------- 1 | /* leetcode 035搜索插入位置search-insert-position JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @param {number} target * @return {number} */ 4 | var searchInsert = function(nums, target) { 5 | for (var i = 0; i <= nums.length; i++) { 6 | var num = nums[i]; 7 | if (target <= num) { 8 | return i; 9 | } 10 | } 11 | return nums.length; 12 | }; -------------------------------------------------------------------------------- /Algorithms/036有效的数独valid-sudoku/valid-sudoku.js: -------------------------------------------------------------------------------- 1 | /* leetcode 036有效的数独valid-sudoku JavaScript实现 */ 2 | 3 | /** * @param {character[][]} board * @return {boolean} */ 4 | var isValidSudoku = function(board) { /* 检查一个数组中是否有重复。*/ 5 | function checkRepeat(arr) { 6 | var numObj = {}; 7 | for (var i = 0; i < arr.length; i++) { 8 | var v = arr[i]; 9 | if (v == '.') { 10 | continue; 11 | } /* 数量为2就就重复了,直接return;*/ 12 | if (!numObj[v]) { 13 | numObj[v] = 1; 14 | } else { 15 | return true; 16 | } 17 | } 18 | return false; 19 | } /* 检查一个数组集合是否合格。*/ 20 | function checkArrRepeat(arr) { 21 | for (var j = 0; j < arr.length; j++) { 22 | if (checkRepeat(arr[j])) { 23 | return true; 24 | } 25 | } 26 | return false; 27 | } /* 每一横行检查*/ 28 | if (checkArrRepeat(board)) { 29 | return false; 30 | } /* 生成竖行*/ 31 | var colArr = []; 32 | board.forEach(function(v, i) { 33 | for (var j = 0; j < 9; j++) { 34 | if (colArr[j] == undefined) { 35 | colArr[j] = []; 36 | } 37 | colArr[j].push(v[j]) 38 | } 39 | }); 40 | if (checkArrRepeat(colArr)) { 41 | return false; 42 | } /* 生成九格。*/ 43 | var box9Arr = []; 44 | for (var x = 0; x < 9; x++) { 45 | for (var y = 0; y < 9; y++) { 46 | var item = board[y][x]; /* 根据x,y坐标计算在大数组中的index。*/ 47 | var index = (Math.floor(x / 3) + 1) + (Math.floor(y / 3)) * 3 - 1; 48 | if (box9Arr[index] == undefined) { 49 | box9Arr[index] = []; 50 | } 51 | box9Arr[index].push(item) 52 | } 53 | } 54 | if (checkArrRepeat(box9Arr)) { 55 | return false; 56 | } 57 | return true; 58 | }; -------------------------------------------------------------------------------- /Algorithms/049字母异位词分组group-anagrams/group-anagrams.js: -------------------------------------------------------------------------------- 1 | /* leetcode 049字母异位词分组group-anagrams JavaScript实现 */ 2 | 3 | /** * @param {string[]} strs * @return {string[][]} */ 4 | var groupAnagrams = function(strs) { 5 | var obj = {}; 6 | for (var i = 0; i < strs.length; i++) { 7 | var str = strs[i]; 8 | var key = strs[i].split('').sort().join(''); 9 | if (!obj[key]) { 10 | obj[key] = []; 11 | } 12 | obj[key].push(str); 13 | } 14 | var res = []; 15 | for (var j in obj) { 16 | if (obj.hasOwnProperty(j)) { 17 | res.push(obj[j]) 18 | } 19 | } 20 | return res; 21 | }; -------------------------------------------------------------------------------- /Algorithms/053最大子序和maximum-subarray/maximum-subarray.js: -------------------------------------------------------------------------------- 1 | /* leetcode 053最大子序和maximum-subarray JavaScript实现 */ 2 | 3 | /*一段一段地计算比较。不以负数开头和结尾。不过要考虑全是负数的情况*/ /*小于0了就重启一段。复杂度O(n);*/ 4 | var maxSubArray = function(nums) { 5 | var max = nums[0]; 6 | var sum = 0; 7 | var len = nums.length; 8 | if (len == 0) { 9 | return 0; 10 | } 11 | for (var i = 0; i < len; i++) { 12 | var item = nums[i]; /* 针对的情况 [-3,-2,1,2,2,0,1,0]*/ 13 | if (sum < 0 && item >= 0) { 14 | sum = item; 15 | max = sum; 16 | } else { 17 | sum += item; 18 | } 19 | if (sum > max) { 20 | max = sum; 21 | } else if (item > max) { 22 | max = item; 23 | } else if (sum < 0) { 24 | sum = 0; 25 | } 26 | } 27 | return max; 28 | }; -------------------------------------------------------------------------------- /Algorithms/056合并区间merge-intervals/merge-intervals.js: -------------------------------------------------------------------------------- 1 | /* leetcode 056合并区间merge-intervals JavaScript实现 */ 2 | 3 | var merge = function(intervals) { /* 保存结果*/ 4 | var res = []; /* 遍历*/ 5 | for (var i = 0; i < intervals.length; i++) { 6 | var item = intervals[i]; /* 系统有bug。传入的不是数组,要这样转一下。*/ 7 | var itemArr = []; 8 | for (var a in item) { 9 | itemArr.push(item[a]) 10 | } 11 | var item0 = itemArr[0]; 12 | var item1 = itemArr[1]; /* 在哪些区间中。*/ 13 | var min = item0; 14 | var max = item1; /* 遍历结果区间。*/ 15 | for (var j = 0; j < res.length;) { 16 | var inItem0 = res[j][0]; 17 | var inItem1 = res[j][1]; /* 如果在结果区间的一些区间范围中。*/ /* 则把结果区间中的对应区间删除,并替换区间最小值,最大值。*/ /* 以实现结果区间中的区间合并。*/ 18 | if ((item0 <= inItem1 && item0 >= inItem0) || (item1 <= inItem1 && item1 >= inItem0) || (item0 <= inItem0 && item1 >= inItem0) ||                 (item0 <= inItem1 && item1 >= inItem1)) { /* 能合起来放到一个数组中。*/ 19 | if (inItem0 < min) { 20 | min = inItem0; 21 | } 22 | if (inItem1 > max) { 23 | max = inItem1; 24 | } /* 从res中删除一个。*/ 25 | res.splice(j, 1); 26 | } else { 27 | j++ 28 | } 29 | } /* 将区间加入进去。这是经过了删除和合并处理后的。*/ 30 | res.push([min, max]); 31 | } 32 | return res; 33 | }; -------------------------------------------------------------------------------- /Algorithms/057插入区间insert-interval/insert-interval.js: -------------------------------------------------------------------------------- 1 | /* leetcode 057插入区间insert-interval JavaScript实现 */ 2 | 3 | /** * Definition for an interval. * function Interval(start, end) { * this.start = start; * this.end = end; * } */ /** * @param {Interval[]} intervals * @param {Interval} newInterval * @return {Interval[]} */ /*合并那个题目的基础上稍微修改一下 加上了合并后的排序*/ 4 | var insert = function(intervals, newInterval) { 5 | intervals = intervals.concat([newInterval]); /* 保存结果*/ 6 | var res = []; /* 遍历*/ 7 | for (var i = 0; i < intervals.length; i++) { 8 | var item = intervals[i]; /* 系统有bug。传入的不是数组,要这样转一下。*/ 9 | var itemArr = []; 10 | for (var a in item) { 11 | if (item.hasOwnProperty(a)) { 12 | itemArr.push(item[a]) 13 | } 14 | } 15 | var item0 = itemArr[0]; 16 | var item1 = itemArr[1]; /* 在哪些区间中。*/ 17 | var min = item0; 18 | var max = item1; /* 遍历结果区间。*/ 19 | for (var j = 0; j < res.length;) { 20 | var inItem0 = res[j][0]; 21 | var inItem1 = res[j][1]; /* 如果在结果区间的一些区间范围中。*/ /* 则把结果区间中的对应区间删除,并替换区间最小值,最大值。*/ /* 以实现结果区间中的区间合并。*/ 22 | if ((item0 <= inItem1 && item0 >= inItem0) || (item1 <= inItem1 && item1 >= inItem0) || (item0 <= inItem0 && item1 >= inItem0) ||                 (item0 <= inItem1 && item1 >= inItem1)) { /* 能合起来放到一个数组中。*/ 23 | if (inItem0 < min) { 24 | min = inItem0; 25 | } 26 | if (inItem1 > max) { 27 | max = inItem1; 28 | } /* 从res中删除一个。*/ 29 | res.splice(j, 1); 30 | } else { 31 | j++ 32 | } 33 | } /* 将区间加入进去。这是经过了删除和合并处理后的。*/ 34 | res.push([min, max]); 35 | } 36 | res.sort(function(a, b) { 37 | return a[0] - b[0] 38 | }); 39 | return res; 40 | }; -------------------------------------------------------------------------------- /Algorithms/058最后一个单词的长度length-of-last-word/length-of-last-word.js: -------------------------------------------------------------------------------- 1 | /* leetcode 058最后一个单词的长度length-of-last-word JavaScript实现 */ 2 | 3 | /** * @param {string} s * @return {number} */ 4 | var lengthOfLastWord = function(s) { 5 | s = s.trim(); 6 | if ('' == s) { 7 | return 0; 8 | } 9 | var sArr = s.split(/\s+/); 10 | return sArr[sArr.length - 1].length; 11 | }; -------------------------------------------------------------------------------- /Algorithms/065有效数字valid-number/valid-number.js: -------------------------------------------------------------------------------- 1 | /* leetcode 065有效数字valid-number JavaScript实现 */ 2 | 3 | /** * @param {string} s * @return {boolean} */ /* 处理" -."*/ /* 处理"+.8"*/ /* 处理"46.e3" true*/ /* 处理".e1" false*/ /* 处理" 005047e+6" true;*/ /* 处理"4e+" false*/ 4 | var isNumber = function(s) { 5 | str = s.trim(); 6 | if (str.length == 0) { 7 | return false; 8 | } 9 | var numReg = /^[+-]?\d*(\.\d*)?(e[+-]?\d+)?$/; 10 | var matchNum = str.match(numReg); 11 | if (matchNum) { 12 | var eIndex = str.indexOf('e'); 13 | if (eIndex == 0 || eIndex == str.length - 1) { 14 | return false; 15 | } else if (eIndex > 0) { 16 | if (str.charAt(eIndex - 1).match(/\d|\./)) { /* 处理" -."*/ 17 | if (str.match(/^[+-]?\.e/)) { 18 | return false; 19 | } 20 | return true; 21 | } 22 | return false; 23 | } 24 | var dIndex = str.indexOf('.'); 25 | if (dIndex == str.length - 1) { 26 | if (dIndex == 0) { 27 | return false; 28 | } /* 处理" -."*/ 29 | if (str.match(/[+-]\.$/)) { 30 | return false; 31 | } 32 | return true; 33 | } else if (dIndex > 0 && !str.charAt(dIndex + 1).match(/\d/)) { 34 | return false; 35 | } 36 | return true; 37 | } 38 | return false; 39 | }; -------------------------------------------------------------------------------- /Algorithms/069x 的平方根sqrtx/sqrtx.js: -------------------------------------------------------------------------------- 1 | /* leetcode 069x 的平方根sqrtx JavaScript实现 */ 2 | 3 | /** * @param {number} num * @return {number} */ 4 | var mySqrt = function(num) { 5 | var i = 0; 6 | while (i <= num) { 7 | var item = i * i; 8 | if (item == num) { 9 | return i; 10 | } 11 | if (item > num) { 12 | return i - 1; 13 | } 14 | i++ 15 | } 16 | }; -------------------------------------------------------------------------------- /Algorithms/070爬楼梯climbing-stairs/climbing-stairs.js: -------------------------------------------------------------------------------- 1 | /* leetcode 070爬楼梯climbing-stairs JavaScript实现 */ 2 | 3 | /** * @param {number} n * @return {number} */ /*已知最后一步可能走2级,也可能走1级。所以f(n-1),f(n-2)之和就是结果了。*/ /*如果一次还可能走3级呢?*/ 4 | var climbStairs = function(n) { 5 | if (!climbStairs.cache) { 6 | climbStairs.cache = {}; 7 | } 8 | var cache = climbStairs.cache; 9 | if (cache[n]) { 10 | return cache[n]; 11 | } 12 | if (n == 1 || n == 0) { 13 | return 1; 14 | } 15 | return cache[n] = climbStairs(n - 1) + climbStairs(n - 2); 16 | }; -------------------------------------------------------------------------------- /Algorithms/088合并两个有序数组merge-sorted-array/merge-sorted-array.js: -------------------------------------------------------------------------------- 1 | /* leetcode 88.合并两个有序数组 JavaScript实现 */ 2 | 3 | var merge = function(nums1, m, nums2, n) { 4 | var dealNum2 = nums2.slice(0, n); 5 | nums1.length = m; 6 | for (var i = 0; i < nums1.length && dealNum2.length > 0; i++) { 7 | var n1 = nums1[i]; 8 | var n2 = dealNum2[0]; /* 比nums1中的数小或等就插入在前面。*/ 9 | if (n2 <= n1) { 10 | nums1.splice(i, 0, n2); 11 | dealNum2.shift(); 12 | } 13 | } /* 剩下的放在后面*/ 14 | if (dealNum2.length > 0) { 15 | [].push.apply(nums1, dealNum2); 16 | } 17 | } -------------------------------------------------------------------------------- /Algorithms/094二叉树的中序遍历binary-tree-inorder-traversal/binary-tree-inorder-traversal.js: -------------------------------------------------------------------------------- 1 | /* leetcode 094二叉树的中序遍历binary-tree-inorder-traversal JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number[]} */ 4 | var inorderTraversal = function(root) { 5 | var res = []; 6 | if (!root) { 7 | return res; 8 | } 9 | var stack = [root]; 10 | while (stack.length > 0) { 11 | var item = stack[stack.length - 1]; 12 | if (!item.left || (item.left && item.left.isOk)) { 13 | stack.pop(); 14 | item.isOk = true; 15 | res.push(item.val); 16 | item.right && stack.push(item.right); 17 | } else if (item.left && !item.left.isOk) { 18 | stack.push(item.left); 19 | } 20 | } 21 | return res; 22 | }; -------------------------------------------------------------------------------- /Algorithms/096不同的二叉搜索树unique-binary-search-trees/unique-binary-search-trees.js: -------------------------------------------------------------------------------- 1 | /* leetcode 96.不同的二叉搜索树 JavaScript实现 */ 2 | 3 | /** * @param {number} n * @return {number} */ 4 | var numTrees = function(n) { 5 | if (n < 2) { 6 | return n; 7 | } 8 | var dp = [1, 1]; /* 从第二个到第n个。*/ 9 | for (var i = 2; i <= n; i++) { 10 | dp[i] = 0; /* 1到i分别作为根节点。用它前面的个数的数量*它后面的个数的数量*/ 11 | for (var j = 1; j <= i; j++) { 12 | dp[i] += dp[j - 1] * dp[i - j]; 13 | } 14 | }; 15 | return dp[n]; 16 | }; -------------------------------------------------------------------------------- /Algorithms/098验证二叉搜索树validate-binary-search-tree/validate-binary-search-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 098验证二叉搜索树validate-binary-search-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {boolean} */ 4 | var isValidBST = function(root) { /* 检测子节点是否符合要求。*/ 5 | var checkChild = function(root, centerVal, dir) { 6 | if (!root) { 7 | return true; 8 | } 9 | var val = root.val; /* 左子树*/ 10 | if (dir == 'left' && val >= centerVal) { 11 | return false; 12 | } /* 右子树*/ 13 | if (dir == 'right' && val <= centerVal) { 14 | return false; 15 | } 16 | return checkChild(root.left, centerVal, dir) && checkChild(root.right, centerVal, dir); 17 | } 18 | 19 | function readNode(root) { 20 | if (!root) { 21 | return true; 22 | } 23 | if ((!checkChild(root.left, root.val, 'left')) || (!checkChild(root.right, root.val, 'right'))) { 24 | return false; 25 | } 26 | return readNode(root.left) && readNode(root.right); 27 | } 28 | return readNode(root); 29 | }; -------------------------------------------------------------------------------- /Algorithms/099恢复二叉搜索树recover-binary-search-tree/recover-binary-search-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 099恢复二叉搜索树recover-binary-search-tree JavaScript实现 */ 2 | 3 | /*中序遍历搜索树。就有序增长的。*/ 4 | var recoverTree = function(root) { 5 | var prev; 6 | var node1; 7 | var node2; 8 | findTwoNode(root); 9 | if (node1 != null && node2 != null) { 10 | var temp = node1.val; 11 | node1.val = node2.val; 12 | node2.val = temp; 13 | } 14 | 15 | function findTwoNode(root) { 16 | if (root == null) return; 17 | findTwoNode(root.left); 18 | if (prev != null && prev.val > root.val) { 19 | if (node1 == null) { 20 | node1 = prev; 21 | } 22 | node2 = root; 23 | } 24 | prev = root; 25 | findTwoNode(root.right); 26 | } 27 | }; -------------------------------------------------------------------------------- /Algorithms/100相同的树same-tree/same-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 100相同的树same-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} p * @param {TreeNode} q * @return {boolean} */ 4 | var isSameTree = function(p, q) { 5 | if (p == null && q != null) { 6 | return false; 7 | } 8 | if (p != null && q == null) { 9 | return false; 10 | } /* 查询到子节点都为null时结束。*/ 11 | if (p == null && q == null) { 12 | return true; 13 | } 14 | if (p.val != q.val) { 15 | return false; 16 | } /* 递归对比左叶与右叶。*/ 17 | return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); 18 | }; -------------------------------------------------------------------------------- /Algorithms/101对称二叉树symmetric-tree/symmetric-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 101对称二叉树symmetric-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {boolean} */ 4 | var isSymmetric = function(root) { 5 | if (!root) { 6 | return true; 7 | } 8 | var Symmetric = function(p, q) { 9 | if (p == null && q != null) { 10 | return false; 11 | } 12 | if (p != null && q == null) { 13 | return false; 14 | } /* 查询到子节点都为null时结束。*/ 15 | if (p == null && q == null) { 16 | return true; 17 | } 18 | if (p.val != q.val) { 19 | return false; 20 | } /* 递归对比左叶与右叶。*/ 21 | return Symmetric(p.left, q.right) && Symmetric(p.right, q.left); 22 | }; 23 | return Symmetric(root.left, root.right); 24 | } -------------------------------------------------------------------------------- /Algorithms/102二叉树的层次遍历binary-tree-level-order-traversal/binary-tree-level-order-traversal.js: -------------------------------------------------------------------------------- 1 | /* leetcode 102二叉树的层次遍历binary-tree-level-order-traversal JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number[][]} */ 4 | var levelOrder = function(root) { 5 | if (root == null) { 6 | return []; 7 | } 8 | var checkArr = [root]; 9 | var resArr = [ 10 | [root.val] 11 | ]; 12 | while (checkArr.length > 0) { 13 | var newCheckArr = []; 14 | for (var i = 0; i < checkArr.length; i++) { 15 | var item = checkArr[i]; 16 | if (item.left) { 17 | newCheckArr.push(item.left); 18 | } 19 | if (item.right) { 20 | newCheckArr.push(item.right); 21 | } 22 | } 23 | checkArr = newCheckArr; 24 | if (checkArr.length > 0) { 25 | var levelArr = checkArr.map(function(v, i) { 26 | return v.val; 27 | }); 28 | resArr.push(levelArr); 29 | } 30 | } 31 | return resArr; 32 | }; -------------------------------------------------------------------------------- /Algorithms/103二叉树的锯齿形层次遍历binary-tree-zigzag-level-order-traversal/binary-tree-zigzag-level-order-traversal.js: -------------------------------------------------------------------------------- 1 | /* leetcode 103二叉树的锯齿形层次遍历binary-tree-zigzag-level-order-traversal JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number[][]} */ 4 | var zigzagLevelOrder = function(root) { 5 | if (root == null) { 6 | return []; 7 | } 8 | var checkArr = [root]; 9 | var resArr = [ 10 | [root.val] 11 | ]; /* 往右*/ 12 | var dir = 'left'; 13 | while (checkArr.length > 0) { 14 | var newCheckArr = []; 15 | for (var i = 0; i < checkArr.length; i++) { 16 | var item = checkArr[i]; 17 | if (item.left) { 18 | newCheckArr.push(item.left); 19 | } 20 | if (item.right) { 21 | newCheckArr.push(item.right); 22 | } 23 | } 24 | checkArr = newCheckArr; 25 | if (checkArr.length > 0) { 26 | var levelArr = checkArr.map(function(v, i) { 27 | return v.val; 28 | }); 29 | if (dir == 'right') { 30 | resArr.push(levelArr); 31 | dir = 'left'; 32 | } else { 33 | resArr.push(levelArr.reverse()); 34 | dir = 'right'; 35 | } 36 | } 37 | } 38 | return resArr; 39 | }; -------------------------------------------------------------------------------- /Algorithms/104二叉树的最大深度maximum-depth-of-binary-tree/maximum-depth-of-binary-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 104二叉树的最大深度maximum-depth-of-binary-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ 4 | var maxDepth = function(root) { 5 | var res = 0; 6 | if (root == null) { 7 | return 0; 8 | } 9 | var checkArr = [root]; 10 | while (checkArr.length > 0) { 11 | res++; 12 | var newCheckArr = []; 13 | checkArr.forEach(function(v, i) { 14 | v.left && newCheckArr.push(v.left); 15 | v.right && newCheckArr.push(v.right); 16 | }); 17 | checkArr = newCheckArr; 18 | } 19 | return res; 20 | }; -------------------------------------------------------------------------------- /Algorithms/105从前序与中序遍历序列构造二叉树construct-binary-tree-from-preorder-and-inorder-traversal/construct-binary-tree-from-preorder-and-inorder-traversal.js: -------------------------------------------------------------------------------- 1 | /* leetcode 105.从前序与中序遍历序列构造二叉树 JavaScript实现 */ 2 | 3 | var buildTree = function(preorder, inorder) { 4 | var len = preorder.length; 5 | if (len == 0) { 6 | return null; 7 | } 8 | if (len == 1) { 9 | return new TreeNode(preorder[0]); 10 | } /* 前序遍历的第一个是根节点。*/ 11 | var rootVal = preorder.shift(); 12 | var root = new TreeNode(rootVal); 13 | var rootIndexInorder = inorder.indexOf(rootVal); /* 左右子树的中序*/ 14 | var leftTreeInorder = inorder.slice(0, rootIndexInorder); 15 | var rightTreeInorder = inorder.slice(rootIndexInorder + 1); /* 在前序中的位置。默认为最后一个,因为它遍历不到。*/ 16 | var preorderSplitIndex = len; 17 | for (var i = 0; i < preorder.length; i++) { 18 | var item = preorder[i]; 19 | if (leftTreeInorder.indexOf(item) < 0) { 20 | preorderSplitIndex = i; 21 | break; 22 | } 23 | } /* 左右子树的前序*/ 24 | var leftTreePreorder = preorder.slice(0, preorderSplitIndex); 25 | var rightTreePreorder = preorder.slice(preorderSplitIndex); /* 递归*/ 26 | root.left = buildTree(leftTreePreorder, leftTreeInorder); 27 | root.right = buildTree(rightTreePreorder, rightTreeInorder); 28 | return root; 29 | }; -------------------------------------------------------------------------------- /Algorithms/106从中序与后序遍历序列构造二叉树construct-binary-tree-from-inorder-and-postorder-traversal/construct-binary-tree-from-inorder-and-postorder-traversal.js: -------------------------------------------------------------------------------- 1 | /* leetcode 106.从中序与后序遍历序列构造二叉树 JavaScript实现 */ 2 | 3 | var buildTree = function(inorder, postorder) { 4 | var len = inorder.length; 5 | if (len == 0) { 6 | return null; 7 | } 8 | if (len == 1) { 9 | return new TreeNode(inorder[0]); 10 | } 11 | var rootVal = postorder.pop(); 12 | var root = new TreeNode(rootVal); 13 | var rootIndexInorder = inorder.indexOf(rootVal); /* 左右子树的中序*/ 14 | var leftTreeInorder = inorder.slice(0, rootIndexInorder); 15 | var rightTreeInorder = inorder.slice(rootIndexInorder + 1); /* 在后序中的位置。默认为最后一个。*/ 16 | var postorderSplitIndex = postorder.length; 17 | for (var i = 0; i < postorder.length; i++) { 18 | var item = postorder[i]; 19 | if (leftTreeInorder.indexOf(item) < 0) { 20 | postorderSplitIndex = i; 21 | break; 22 | } 23 | } /* 左右子树的后序*/ 24 | var leftTreePostorder = postorder.slice(0, postorderSplitIndex); 25 | var rightTreePostorder = postorder.slice(postorderSplitIndex); /* 递归*/ 26 | root.left = buildTree(leftTreeInorder, leftTreePostorder); 27 | root.right = buildTree(rightTreeInorder, rightTreePostorder); 28 | return root; 29 | }; -------------------------------------------------------------------------------- /Algorithms/108将有序数组转换为二叉搜索树convert-sorted-array-to-binary-search-tree/convert-sorted-array-to-binary-search-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 108将有序数组转换为二叉搜索树convert-sorted-array-to-binary-search-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {number[]} nums * @return {TreeNode} */ 4 | var sortedArrayToBST = function(nums) { 5 | var len = nums.length; 6 | var mid = Math.floor(len / 2); 7 | if (len == 0) { 8 | return null; 9 | } 10 | var node = new TreeNode(nums[mid]); 11 | if (mid > 0) { 12 | node.left = sortedArrayToBST(nums.slice(0, mid)); 13 | } 14 | if (mid + 1 <= len) { 15 | node.right = sortedArrayToBST(nums.slice(mid + 1)); 16 | } 17 | return node; 18 | }; -------------------------------------------------------------------------------- /Algorithms/109有序链表转换二叉搜索树convert-sorted-list-to-binary-search-tree/convert-sorted-list-to-binary-search-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 109有序链表转换二叉搜索树convert-sorted-list-to-binary-search-tree JavaScript实现 */ 2 | 3 | /*先转成数组*/ 4 | var sortedListToBST = function(head) { 5 | var arr = []; 6 | if (head == null) { 7 | arr = []; 8 | } 9 | var next = head; 10 | while (next) { 11 | arr.push(next.val); 12 | next = next.next; 13 | } 14 | var sortedArrayToBST = function(nums) { 15 | var len = nums.length; 16 | var mid = Math.floor(len / 2); 17 | if (len == 0) { 18 | return null; 19 | } 20 | var node = new TreeNode(nums[mid]); 21 | if (mid > 0) { 22 | node.left = sortedArrayToBST(nums.slice(0, mid)); 23 | } 24 | if (mid + 1 <= len) { 25 | node.right = sortedArrayToBST(nums.slice(mid + 1)); 26 | } 27 | return node; 28 | }; 29 | return sortedArrayToBST(arr); 30 | } -------------------------------------------------------------------------------- /Algorithms/110平衡二叉树balanced-binary-tree/balanced-binary-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 110平衡二叉树balanced-binary-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {boolean} */ 4 | var isBalanced = function(root) { 5 | if (!root) { 6 | return true; 7 | } 8 | if (Math.abs(nodeHeight(root.left) - nodeHeight(root.right)) > 1) { 9 | return false; 10 | } else { 11 | return isBalanced(root.left) && isBalanced(root.right); 12 | } 13 | 14 | function nodeHeight(node) { 15 | if (node == null) { 16 | return 0; 17 | } 18 | return Math.max(nodeHeight(node.left), nodeHeight(node.right)) + 1; 19 | } 20 | } -------------------------------------------------------------------------------- /Algorithms/111二叉树的最小深度minimum-depth-of-binary-tree/minimum-depth-of-binary-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 111二叉树的最小深度minimum-depth-of-binary-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number} */ 4 | var minDepth = function(root) { 5 | var res = 0; 6 | if (root == null) { 7 | return 0; 8 | } 9 | var checkArr = [root]; 10 | while (checkArr.length > 0) { 11 | res++; 12 | var newCheckArr = []; /* 注意checkArr.some有满足的就停止迭代。*/ 13 | if (checkArr.some(function(v, i) { 14 | v.left && newCheckArr.push(v.left); 15 | v.right && newCheckArr.push(v.right); 16 | return !v.left && !v.right; 17 | })) { 18 | return res; 19 | }; 20 | checkArr = newCheckArr; 21 | } 22 | return res; 23 | }; -------------------------------------------------------------------------------- /Algorithms/112路径总和path-sum/path-sum.js: -------------------------------------------------------------------------------- 1 | /* leetcode 112路径总和path-sum JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @param {number} sum * @return {boolean} */ 4 | var hasPathSum = function(root, sum) { /* 递归的时候把上一级的path和结论的arr传入。*/ 5 | var binaryTreePaths = function(root, path) { 6 | if (!root) { 7 | return false; 8 | } 9 | var val = root.val; 10 | path = path ? path + '->' + val : val.toString(); 11 | if (!root.left && !root.right) { 12 | if (path.split('->').reduce(function(a, b) { 13 | return a + Number(b); 14 | }, 0) == sum) { 15 | return true; 16 | } 17 | return false; 18 | } else { 19 | return (root.left && binaryTreePaths(root.left, path)) || (root.right && binaryTreePaths(root.right, path)); 20 | } 21 | return false; 22 | } 23 | return binaryTreePaths(root) || false; 24 | }; -------------------------------------------------------------------------------- /Algorithms/113路径总和 IIpath-sum-ii/path-sum-ii.js: -------------------------------------------------------------------------------- 1 | /* leetcode 113路径总和 IIpath-sum-ii JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @param {number} sum * @return {number[][]} */ 4 | var pathSum = function(root, sum) { /* 递归的时候把上一级的path和结论的arr传入。*/ 5 | var binaryTreePaths = function(root, path, arr) { 6 | if (!root) { 7 | return []; 8 | } 9 | if (!arr) { 10 | arr = []; 11 | } 12 | var val = root.val; 13 | path = path ? path + '->' + val : val.toString(); 14 | if (!root.left && !root.right) { 15 | var resPath = path.split('->').map(function(v) { 16 | return Number(v); 17 | }); 18 | if (resPath.reduce(function(a, b) { 19 | return a + Number(b); 20 | }, 0) == sum) { 21 | arr.push(resPath); 22 | } 23 | } else { 24 | root.left && binaryTreePaths(root.left, path, arr); 25 | root.right && binaryTreePaths(root.right, path, arr); 26 | } 27 | return arr; 28 | } 29 | return binaryTreePaths(root); 30 | }; -------------------------------------------------------------------------------- /Algorithms/116填充同一层的兄弟节点populating-next-right-pointers-in-each-node/populating-next-right-pointers-in-each-node.js: -------------------------------------------------------------------------------- 1 | /* leetcode 116填充同一层的兄弟节点populating-next-right-pointers-in-each-node JavaScript实现 */ 2 | 3 | /** * Definition for binary tree with next pointer. * function TreeLinkNode(val) { * this.val = val; * this.left = this.right = this.next = null; * } */ /** * @param {TreeLinkNode} root * @return {void} Do not return anything, modify tree in-place instead. */ 4 | var connect = function(root) { 5 | if (root != null) { 6 | var checkArr = [root]; 7 | while (checkArr.length > 0) { 8 | var newCheckArr = []; 9 | for (var i = 0; i < checkArr.length; i++) { 10 | var item = checkArr[i]; 11 | item.next = checkArr[i + 1] || null; 12 | if (item.left) { 13 | newCheckArr.push(item.left); 14 | } 15 | if (item.right) { 16 | newCheckArr.push(item.right); 17 | } 18 | } 19 | checkArr = newCheckArr; 20 | } 21 | } 22 | }; -------------------------------------------------------------------------------- /Algorithms/117填充同一层的兄弟节点 IIpopulating-next-right-pointers-in-each-node-ii/populating-next-right-pointers-in-each-node-ii.js: -------------------------------------------------------------------------------- 1 | /* leetcode 117填充同一层的兄弟节点 IIpopulating-next-right-pointers-in-each-node-ii JavaScript实现 */ 2 | 3 | /** * Definition for binary tree with next pointer. * function TreeLinkNode(val) { * this.val = val; * this.left = this.right = this.next = null; * } */ /** * @param {TreeLinkNode} root * @return {void} Do not return anything, modify tree in-place instead. */ 4 | var connect = function(root) { 5 | if (root != null) { 6 | var checkArr = [root]; 7 | while (checkArr.length > 0) { 8 | var newCheckArr = []; 9 | for (var i = 0; i < checkArr.length; i++) { 10 | var item = checkArr[i]; 11 | item.next = checkArr[i + 1] || null; 12 | if (item.left) { 13 | newCheckArr.push(item.left); 14 | } 15 | if (item.right) { 16 | newCheckArr.push(item.right); 17 | } 18 | } 19 | checkArr = newCheckArr; 20 | } 21 | } 22 | }; -------------------------------------------------------------------------------- /Algorithms/118杨辉三角pascals-triangle/pascals-triangle.js: -------------------------------------------------------------------------------- 1 | /* leetcode 118杨辉三角pascals-triangle JavaScript实现 */ 2 | 3 | /** * @param {number} numRows * @return {number[][]} */ 4 | var generate = function(numRows) { /* 一个数组,保存上一行值*/ 5 | var resArr = []; 6 | var arr = []; 7 | for (var i = 0; i < numRows; i++) { 8 | var arr1 = []; /* 有第一个就加进去。*/ 9 | if (arr[0]) { 10 | arr1.push(arr[0]); 11 | } 12 | var j = 0; /* 如果有下一个,就加一个。*/ 13 | while (arr[j + 1]) { 14 | arr1.push(arr[j] + arr[j + 1]); 15 | j++; 16 | } /* 最后再加一个1*/ 17 | arr1.push(1); /* 把值给arr以进行下一轮计算。*/ 18 | arr = arr1; 19 | resArr.push(arr); 20 | } 21 | return resArr; 22 | }; -------------------------------------------------------------------------------- /Algorithms/119杨辉三角 IIpascals-triangle-ii/pascals-triangle-ii.js: -------------------------------------------------------------------------------- 1 | /* leetcode 119杨辉三角 IIpascals-triangle-ii JavaScript实现 */ 2 | 3 | /** * @param {number} rowIndex * @return {number[]} */ 4 | var getRow = function(k) { /* 一个数组,保存上一行值*/ 5 | var arr = []; 6 | for (var i = 0; i <= k; i++) { 7 | var arr1 = []; /* 有第一个就加进去。*/ 8 | if (arr[0]) { 9 | arr1.push(arr[0]); 10 | } 11 | var j = 0; /* 如果有下一个,就加一个。*/ 12 | while (arr[j + 1]) { 13 | arr1.push(arr[j] + arr[j + 1]); 14 | j++; 15 | } /* 最后再加一个1*/ 16 | arr1.push(1); /* 把值给arr以进行下一轮计算。*/ 17 | arr = arr1; 18 | } 19 | return arr; 20 | }; -------------------------------------------------------------------------------- /Algorithms/121买卖股票的最佳时机best-time-to-buy-and-sell-stock/best-time-to-buy-and-sell-stock.js: -------------------------------------------------------------------------------- 1 | /* leetcode 121买卖股票的最佳时机best-time-to-buy-and-sell-stock JavaScript实现 */ 2 | 3 | var maxProfit = function(prices) { 4 | var n = prices.length; 5 | var maxProfit = 0; 6 | if (n < 2) { 7 | return maxProfit; 8 | } 9 | var min = prices[0]; 10 | for (var i = 1; i < n; i++) { 11 | var item = prices[i]; 12 | if (item <= min) { 13 | min = item; 14 | } else { 15 | maxProfit = Math.max(item - min, maxProfit); 16 | } 17 | } 18 | return maxProfit; 19 | }; -------------------------------------------------------------------------------- /Algorithms/122买卖股票的最佳时机 IIbest-time-to-buy-and-sell-stock-ii/best-time-to-buy-and-sell-stock-ii.js: -------------------------------------------------------------------------------- 1 | /* leetcode 122买卖股票的最佳时机 IIbest-time-to-buy-and-sell-stock-ii JavaScript实现 */ 2 | 3 | /** * @param {number[]} prices * @return {number} */ 4 | var maxProfit = function(prices) { 5 | var n = prices.length; 6 | var maxProfit = 0; 7 | if (n < 2) { 8 | return maxProfit; 9 | } 10 | var min = prices[0]; /* 比前面一个数大,就加上与前面一个数的差。*/ /* 比前面的小,就以当前这个数为最小数。*/ 11 | for (var i = 1; i < n; i++) { 12 | var item = prices[i]; 13 | var prev = prices[i - 1]; 14 | if (item >= prev) { 15 | maxProfit = maxProfit + (item - prev); 16 | } else { 17 | min = item; 18 | } 19 | } 20 | return maxProfit; 21 | }; -------------------------------------------------------------------------------- /Algorithms/125验证回文串valid-palindrome/valid-palindrome.js: -------------------------------------------------------------------------------- 1 | /* leetcode 125验证回文串valid-palindrome JavaScript实现 */ 2 | 3 | /** * @param {string} s * @return {boolean} */ 4 | var isPalindrome = function(s) { 5 | if (s.length == 0) { 6 | return true; 7 | } 8 | var s1 = s.toLocaleLowerCase(); /* 正则替换掉*/ 9 | var s2 = s1.replace(/\W|_/g, ''); 10 | return s2.split('').reverse().join('') == s2; 11 | }; -------------------------------------------------------------------------------- /Algorithms/128最长连续序列longest-consecutive-sequence/longest-consecutive-sequence.js: -------------------------------------------------------------------------------- 1 | /* leetcode 128最长连续序列longest-consecutive-sequence JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @return {number} */ 4 | var longestConsecutive = function(nums) { 5 | var item; 6 | var maxCount = 1; 7 | var sortCount = 1; 8 | var sortedNums = nums.sort(function(a, b) { 9 | return a - b; 10 | }); 11 | if (nums.length == 0) { 12 | return 0; 13 | } 14 | var last = sortedNums[0]; 15 | for (var i = 1; i < sortedNums.length; i++) { 16 | item = sortedNums[i]; /* 相等的跳过*/ 17 | if (item - last == 0) { /* 连续的。*/ } else if (item - last == 1) { 18 | sortCount++; /* 不连续,重新计算。*/ 19 | if (sortCount > maxCount) { 20 | maxCount = sortCount; 21 | } 22 | } else { 23 | sortCount = 1; 24 | } 25 | last = item; 26 | } 27 | return maxCount; 28 | }; -------------------------------------------------------------------------------- /Algorithms/129求根到叶子节点数字之和sum-root-to-leaf-numbers/sum-root-to-leaf-numbers.js: -------------------------------------------------------------------------------- 1 | /* leetcode 129求根到叶子节点数字之和sum-root-to-leaf-numbers JavaScript实现 */ 2 | 3 | /*先求出所有的路径,前面有个题目有方法。然后计算一下。*/ 4 | function sumNumbers(root) { /* 递归的时候把上一级的path和结论的arr传入。*/ 5 | var binaryTreePaths = function(root, path, arr) { 6 | if (!root) { 7 | return []; 8 | } 9 | if (!arr) { 10 | arr = []; 11 | } 12 | var val = root.val.toString(); 13 | path = path ? path + '->' + val : val; 14 | if (!root.left && !root.right) { 15 | arr.push(path); 16 | } else { 17 | root.left && binaryTreePaths(root.left, path, arr); 18 | root.right && binaryTreePaths(root.right, path, arr); 19 | } 20 | return arr; 21 | } 22 | var pathArr = binaryTreePaths(root); 23 | return pathArr.reduce(function(a, b) { 24 | return a + Number(b.split('->').join('')); 25 | }, 0); 26 | } -------------------------------------------------------------------------------- /Algorithms/136只出现一次的数字single-number/single-number.js: -------------------------------------------------------------------------------- 1 | /* leetcode 136只出现一次的数字single-number JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @return {number} */ 4 | var singleNumber = function(nums) { 5 | var len = nums.length; 6 | var item; 7 | var cache = {} /* indexOf与lastIndexOf比较。如是一样。说明只有一个。*/ 8 | for (var i = 0; i < len; i++) { 9 | item = nums[i]; 10 | if (!cache[item]) { 11 | cache[item] = 0; 12 | } 13 | cache[item]++; /* 如果是2了,就删除它。*/ 14 | if (cache[item] == 2) { 15 | delete cache[item]; 16 | } 17 | } 18 | for (var i in cache) { 19 | if (cache.hasOwnProperty(i)) { 20 | return parseInt(i, 10); 21 | } 22 | } 23 | }; -------------------------------------------------------------------------------- /Algorithms/141环形链表linked-list-cycle/linked-list-cycle.js: -------------------------------------------------------------------------------- 1 | /* leetcode 141环形链表linked-list-cycle JavaScript实现 */ 2 | 3 | /** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */ /** * @param {ListNode} head * @return {boolean} */ /*环并不一定是首尾连接*/ 4 | var hasCycle = function(head) { 5 | if (head == null) { 6 | return false; 7 | } 8 | if (head.next == null) { 9 | return false; 10 | } 11 | if (head.next.next == null) { 12 | return false; 13 | } 14 | var slow = head; 15 | var fast = head; 16 | while (fast != null && fast.next != null) { 17 | slow = slow.next; 18 | fast = fast.next.next; 19 | if (slow == fast) { 20 | return true; 21 | } 22 | } 23 | return false; 24 | }; -------------------------------------------------------------------------------- /Algorithms/144二叉树的前序遍历binary-tree-preorder-traversal/binary-tree-preorder-traversal.js: -------------------------------------------------------------------------------- 1 | /* leetcode 144二叉树的前序遍历binary-tree-preorder-traversal JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number[]} */ 4 | var preorderTraversal = function(root) { 5 | var res = []; 6 | if (!root) { 7 | return res; 8 | } 9 | var stack = [root]; 10 | while (stack.length > 0) { /* 取第一个。*/ 11 | var item = stack.shift(); 12 | res.push(item.val); 13 | if (item.right) { 14 | stack.unshift(item.right); 15 | } 16 | if (item.left) { 17 | stack.unshift(item.left); 18 | } 19 | } 20 | return res; 21 | }; -------------------------------------------------------------------------------- /Algorithms/145二叉树的后序遍历binary-tree-postorder-traversal/binary-tree-postorder-traversal.js: -------------------------------------------------------------------------------- 1 | /* leetcode 145二叉树的后序遍历binary-tree-postorder-traversal JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number[]} */ 4 | var postorderTraversal = function(root) { 5 | var res = []; 6 | if (!root) { 7 | return res; 8 | } 9 | var stack = [root]; 10 | while (stack.length > 0) { 11 | var item = stack[stack.length - 1]; /* 满足这些就可以直接输出它了。它是叶子节点。或它的子节点都ok了。*/ 12 | if ((item.left == null && item.right == null) || (item.left && item.left.isOk && item.right && item.right.isOk) || (item.left &&             item.left.isOk && item.right == null) || (item.left == null && item.right && item.right.isOk)) { 13 | item.isOk = true; 14 | res.push(item.val); 15 | stack.pop(); 16 | } else if (item.left && !item.left.isOk) { /* 如果左边的没ok,就把左边的入栈*/ 17 | stack.push(item.left); 18 | } else if (item.right && !item.right.isOk) { /* 如果右边的没ok就把右边的入栈。*/ 19 | stack.push(item.right); 20 | } 21 | } 22 | return res; 23 | }; -------------------------------------------------------------------------------- /Algorithms/148排序链表sort-list/sort-list.js: -------------------------------------------------------------------------------- 1 | /* leetcode 148.排序链表 JavaScript实现 */ 2 | 3 | /** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */ 4 | /** * @param {ListNode} head * @return {ListNode} */ 5 | var sortList = function(head) { 6 | if (!head) { 7 | return null; 8 | } 9 | var res; 10 | var arr = []; 11 | var next = head; /* 转数组*/ 12 | while (next) { 13 | arr.push(next.val); 14 | next = next.next; 15 | } /* 数组排序。*/ 16 | arr.sort(function(a, b) { 17 | return a - b; 18 | }); 19 | res = new ListNode(arr[0]); 20 | next = res; 21 | for (var i = 1; i < arr.length; i++) { 22 | next.next = new ListNode(arr[i]); 23 | next = next.next; 24 | } 25 | return res; 26 | }; -------------------------------------------------------------------------------- /Algorithms/167两数之和 II - 输入有序数组two-sum-ii-input-array-is-sorted/two-sum-ii-input-array-is-sorted.js: -------------------------------------------------------------------------------- 1 | /* leetcode 167两数之和 II - 输入有序数组two-sum-ii-input-array-is-sorted JavaScript实现 */ 2 | 3 | /** * @param {number[]} numbers * @param {number} target * @return {number[]} */ 4 | var twoSum = function(numbers, target) { 5 | for (var i = 0; i < numbers.length; i++) { 6 | for (var j = i + 1; j < numbers.length; j++) { 7 | var num1 = numbers[i]; 8 | var num2 = numbers[j]; 9 | if (num1 + num2 == target) { 10 | return [i + 1, j + 1]; 11 | } 12 | } 13 | } 14 | }; -------------------------------------------------------------------------------- /Algorithms/168Excel表列名称excel-sheet-column-title/excel-sheet-column-title.js: -------------------------------------------------------------------------------- 1 | /* leetcode 168Excel表列名称excel-sheet-column-title JavaScript实现 */ 2 | 3 | /** * @param {number} n * @return {string} */ 4 | var convertToTitle = function(n) { 5 | var arr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); 6 | var map = {}; /* 每个字母的序号映射*/ 7 | arr.forEach(function(v, i) { 8 | map[i + 1] = v; 9 | }); /* 进制转换?*/ 10 | var resArr = []; 11 | while (true) { 12 | var rest = n % 26; /* 除得尽,说明是26。*/ 13 | if (rest == 0) { 14 | rest = 26; 15 | } 16 | resArr.push(map[rest]); 17 | n = (n - rest) / 26; 18 | if (n < 1) { 19 | break; 20 | } 21 | } 22 | return resArr.reverse().join(''); 23 | }; -------------------------------------------------------------------------------- /Algorithms/169求众数majority-element/majority-element.js: -------------------------------------------------------------------------------- 1 | /* leetcode 169求众数majority-element JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @return {number} */ 4 | var majorityElement = function(nums) { 5 | var len = nums.length; 6 | var halfLen = len / 2; 7 | var item; 8 | var cache = {}; 9 | for (var i = 0; i < len; i++) { 10 | item = nums[i]; 11 | if (cache[item] === undefined) { 12 | cache[item] = 1; 13 | } else { 14 | cache[item]++; 15 | } 16 | if (cache[item] > halfLen) { 17 | return item; 18 | } 19 | } 20 | }; -------------------------------------------------------------------------------- /Algorithms/171Excel表列序号excel-sheet-column-number/excel-sheet-column-number.js: -------------------------------------------------------------------------------- 1 | /* leetcode 171Excel表列序号excel-sheet-column-number JavaScript实现 */ 2 | 3 | /** * @param {string} s * @return {number} */ 4 | var titleToNumber = function(s) { 5 | var arr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); 6 | var map = {}; /* 每个字母的序号映射*/ 7 | arr.forEach(function(v, i) { 8 | map[v] = i + 1; 9 | }); /* 反转一下,从低位开始算。同时也让次方的index正确。*/ 10 | var sArr = s.split('').reverse(); 11 | var res = 0; /* 26进制转换?不过没有0.*/ 12 | sArr.forEach(function(v, i) { 13 | res = res + map[v] * Math.pow(26, i); 14 | }); 15 | return res; 16 | }; -------------------------------------------------------------------------------- /Algorithms/173二叉搜索树迭代器binary-search-tree-iterator/binary-search-tree-iterator.js: -------------------------------------------------------------------------------- 1 | /* leetcode 173二叉搜索树迭代器binary-search-tree-iterator JavaScript实现 */ 2 | 3 | /** * Definition for binary tree * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @constructor * @param {TreeNode} root - root of the binary search tree */ 4 | var BSTIterator = function(root) { 5 | var readRoot = function(root, callback) { 6 | if (!root) { 7 | return; 8 | } 9 | root.left && readRoot(root.left, callback); 10 | callback && callback(root.val); 11 | root.right && readRoot(root.right, callback); 12 | } 13 | var arr = []; 14 | readRoot(root, function(v) { 15 | arr.push(v); 16 | }); /* 将节点升序保存到一个数组*/ 17 | this.arr = arr; 18 | this.index = 0; 19 | }; /** * @this BSTIterator * @returns {boolean} - whether we have a next smallest number */ 20 | BSTIterator.prototype.hasNext = function() { 21 | if (this.index < this.arr.length) { 22 | return true; 23 | } 24 | return false; 25 | }; /** * @this BSTIterator * @returns {number} - the next smallest number */ 26 | BSTIterator.prototype.next = function() { 27 | var res = this.arr[this.index]; 28 | this.index++; 29 | return res; 30 | }; /** * Your BSTIterator will be called like this: * var i = new BSTIterator(root), a = []; * while (i.hasNext()) a.push(i.next());*/ -------------------------------------------------------------------------------- /Algorithms/179最大数largest-number/largest-number.js: -------------------------------------------------------------------------------- 1 | /* leetcode 179最大数largest-number JavaScript实现 */ 2 | 3 | /*20180429*/ /*一些考虑的情况 128,12;121,12; 3, 30, 34; 883,8; 8308,830;85,87*/ 4 | var largestNumber = function(nums) { 5 | var sortedStrs = nums.map(function(v) { 6 | return v.toString(); 7 | }); 8 | var sortedNums = sortedStrs.sort(function(a, b) { 9 | a = a.toString(); 10 | b = b.toString(); 11 | var aLen = a.length; 12 | var bLen = b.length; /* 将自身重复一直到n位。*/ 13 | function fix(str, len) { 14 | var res = ''; 15 | if (str == '') { 16 | return ''; 17 | } 18 | while (res.length < len) { 19 | res += str; 20 | } 21 | return res.slice(0, len); 22 | } /* 在长度不同且一个包含另一个的时候才需要这样对比。*/ 23 | if (aLen != bLen && (a.indexOf(b) == 0 || b.indexOf(a) == 0)) { /* a长,给b加。用自身填满自己,使两个数据一样长再进行对比。*/ 24 | if (aLen > bLen) { 25 | b = fix(b, aLen); 26 | } else { 27 | a = fix(a, bLen); 28 | } 29 | } /* 有可能出现结果一样的情况。*/ 30 | if (a == b) { 31 | if (aLen > bLen) { 32 | var toCompare = a.slice(bLen); 33 | var maxLen = Math.max(toCompare.length, b.length); 34 | if (fix(toCompare, maxLen) < fix(b, maxLen)) { 35 | return -1; 36 | } else { 37 | return 1; 38 | } 39 | } else { /* 去掉相同的。*/ 40 | var toCompare = b.slice(aLen); 41 | var maxLen = Math.max(toCompare.length, a.length); /* 循环去除掉与b一样的。用剩下的再做一次补齐对比。*/ 42 | if (fix(a, maxLen) < fix(toCompare, maxLen)) { 43 | return -1; 44 | } else { 45 | return 1; 46 | } 47 | } 48 | } else if (a < b) { 49 | return -1; 50 | } else { 51 | return 1; 52 | } 53 | }); 54 | var res = sortedNums.reverse().join(''); /* 把前面多余的0去掉。*/ 55 | var res = res.replace(/^[0]*/, ''); 56 | if (res.length == 0) { 57 | return '0'; 58 | } 59 | return res; 60 | }; -------------------------------------------------------------------------------- /Algorithms/198打家劫舍house-robber/house-robber.js: -------------------------------------------------------------------------------- 1 | /* leetcode 198打家劫舍house-robber JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @return {number} */ 4 | var rob = function(nums) { 5 | var len = nums.length; 6 | if (len < 2) { 7 | return nums[len - 1] ? nums[len - 1] : 0; 8 | } 9 | var dp = [nums[0], Math.max(nums[0], nums[1])]; 10 | for (var i = 2; i < len; i++) { 11 | dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]); 12 | } 13 | return dp[len - 1]; 14 | }; -------------------------------------------------------------------------------- /Algorithms/199二叉树的右视图binary-tree-right-side-view/binary-tree-right-side-view.js: -------------------------------------------------------------------------------- 1 | /* leetcode 199二叉树的右视图binary-tree-right-side-view JavaScript实现 */ 2 | 3 | /*层次遍历返回每层最右一个。*/ 4 | var rightSideView = function(root) { 5 | if (root == null) { 6 | return []; 7 | } 8 | var checkArr = [root]; 9 | var resArr = [root.val]; 10 | while (checkArr.length > 0) { 11 | var newCheckArr = []; 12 | for (var i = 0; i < checkArr.length; i++) { 13 | var item = checkArr[i]; 14 | if (item.left) { 15 | newCheckArr.push(item.left); 16 | } 17 | if (item.right) { 18 | newCheckArr.push(item.right); 19 | } 20 | } 21 | checkArr = newCheckArr; 22 | if (checkArr.length > 0) { 23 | resArr.push(checkArr[checkArr.length - 1].val); 24 | } 25 | } 26 | return resArr; 27 | }; -------------------------------------------------------------------------------- /Algorithms/202快乐数happy-number/happy-number.js: -------------------------------------------------------------------------------- 1 | /* leetcode 202快乐数happy-number JavaScript实现 */ 2 | 3 | /** * @param {number} n * @return {boolean} */ /* 这个题目做得不够好。完全是通过暴力的方式通过的。没有去找规律。*/ 4 | var isHappy = function(n) { /* 计算一个数字的每一位的平方和。*/ 5 | function getSum(n) { 6 | var nStr = n.toString(); 7 | var nArr = nStr.split(''); 8 | return nArr.reduce(function(a, b) { 9 | return a + Math.pow(b, 2); 10 | }, 0) 11 | } 12 | n = getSum(n); 13 | var time = new Date().getTime(); /* 无限循环了就返回false。*/ 14 | try { 15 | while (n != 1) { 16 | n = getSum(n); 17 | var time1 = new Date().getTime(); /* 运行大于20ms,返回false*/ 18 | if (time1 - time > 20) { 19 | return false; 20 | } 21 | } 22 | return true; 23 | } catch (e) { 24 | return false; 25 | } 26 | }; -------------------------------------------------------------------------------- /Algorithms/205同构字符串isomorphic-strings/isomorphic-strings.js: -------------------------------------------------------------------------------- 1 | /* leetcode 205同构字符串isomorphic-strings JavaScript实现 */ 2 | 3 | /** * @param {string} s * @param {string} t * @return {boolean} */ /*另一种错误的答案是看结构[1,2,1,4]这种没有考虑映射相同字符等等。只是基本的格式相同。*/ 4 | var isIsomorphic = function(s, t) { 5 | var sArr = s.split(''); 6 | var tArr = t.split(''); 7 | var sLen = sArr.length; 8 | var tLen = tArr.length; 9 | if (sLen != tLen) { 10 | return false; 11 | } 12 | var sObj = {}; 13 | var tObj = {}; 14 | for (var i = 0; i < sLen; i++) { 15 | var sItem = sArr[i]; 16 | var tItem = tArr[i]; /* 要么两个都有,要么两个都没有。*/ 17 | if (!sObj[sItem] && !tObj[tItem]) { 18 | sObj[sItem] = tItem; 19 | tObj[tItem] = sItem; 20 | } else if (!sObj[sItem] || !tObj[tItem]) { /* 如果一个有,另一个没有,说明不匹配*/ 21 | return false; 22 | } else if (sObj[sItem] != tItem || tObj[tItem] != sItem) { 23 | return false; 24 | } 25 | } 26 | return true; 27 | }; -------------------------------------------------------------------------------- /Algorithms/217存在重复元素contains-duplicate/contains-duplicate.js: -------------------------------------------------------------------------------- 1 | /* leetcode 217存在重复元素contains-duplicate JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @return {boolean} */ 4 | var containsDuplicate = function(nums) { 5 | var len = nums.length; 6 | var minNum = 2; 7 | var item; 8 | var cache = {}; 9 | for (var i = 0; i < len; i++) { 10 | item = nums[i]; 11 | if (cache[item] === undefined) { 12 | cache[item] = 1; 13 | } else { 14 | cache[item]++; 15 | } 16 | if (cache[item] >= minNum) { 17 | return true; 18 | } 19 | } 20 | return false; 21 | }; -------------------------------------------------------------------------------- /Algorithms/219存在重复元素 IIcontains-duplicate-ii/contains-duplicate-ii.js: -------------------------------------------------------------------------------- 1 | /* leetcode 219存在重复元素 IIcontains-duplicate-ii JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @param {number} k * @return {boolean} */ 4 | var containsNearbyDuplicate = function(nums, k) { 5 | var len = nums.length; 6 | var minNum = 2; 7 | var item; 8 | var cache = {}; /* cache中记录上一个这个值的索引。每次循环到的时候,与上一个保存的值求差。*/ 9 | for (var i = 0; i < len; i++) { 10 | item = nums[i]; 11 | if (cache[item] !== undefined && i - cache[item] <= k) { 12 | return true; 13 | } 14 | cache[item] = i; 15 | } 16 | return false; 17 | }; -------------------------------------------------------------------------------- /Algorithms/220存在重复元素 IIIcontains-duplicate-iii/contains-duplicate-iii.js: -------------------------------------------------------------------------------- 1 | /* leetcode 220存在重复元素 IIIcontains-duplicate-iii JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @param {number} k * @param {number} t * @return {boolean} */ 4 | var containsNearbyAlmostDuplicate = function(nums, k, t) { 5 | var len = nums.length; 6 | var item, item1; /* cache中记录上一个这个值的索引。每次循环到的时候,与上一个保存的值求差。*/ 7 | for (var i = 0; i < len; i++) { 8 | item = nums[i]; /* 循环小于k的索引*/ 9 | for (var j = i + 1; j < len && j <= i + k; j++) { 10 | item1 = nums[j]; /* 判断绝对差值*/ 11 | if (Math.abs(item1 - item) <= t) { 12 | return true; 13 | } 14 | } 15 | } 16 | return false; 17 | }; -------------------------------------------------------------------------------- /Algorithms/226翻转二叉树invert-binary-tree/invert-binary-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 226翻转二叉树invert-binary-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ 4 | var invertTree = function(root) { 5 | if (root == null) { 6 | return root; 7 | } 8 | var left = root.left; 9 | var right = root.right; 10 | if (left == null && right == null) { 11 | return root; 12 | } 13 | root.left = invertTree(right); 14 | root.right = invertTree(left); 15 | return root; 16 | }; -------------------------------------------------------------------------------- /Algorithms/229求众数 IImajority-element-ii/majority-element-ii.js: -------------------------------------------------------------------------------- 1 | /* leetcode 229求众数 IImajority-element-ii JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @return {number[]} */ 4 | var majorityElement = function(nums) { 5 | var len = nums.length; 6 | var thirdLen = len / 3; 7 | var item; 8 | var cache = {}; 9 | var res = []; 10 | for (var i = 0; i < len; i++) { 11 | item = nums[i]; 12 | if (cache[item] === undefined) { 13 | cache[item] = 1; 14 | } else { 15 | cache[item]++; 16 | } 17 | if (cache[item] > thirdLen && res.indexOf(item) < 0) { 18 | res.push(item); 19 | } 20 | } 21 | return res; 22 | }; -------------------------------------------------------------------------------- /Algorithms/230二叉搜索树中第K小的元素kth-smallest-element-in-a-bst/kth-smallest-element-in-a-bst.js: -------------------------------------------------------------------------------- 1 | /* leetcode 230二叉搜索树中第K小的元素kth-smallest-element-in-a-bst JavaScript实现 */ 2 | 3 | /*二叉搜索树中序遍历的结果是一个有序数组。*/ 4 | var kthSmallest = function(root, k) { 5 | var readRoot = function(root, callback) { 6 | if (!root) { 7 | return; 8 | } 9 | root.left && readRoot(root.left, callback); 10 | callback && callback(root.val); 11 | root.right && readRoot(root.right, callback); 12 | } 13 | var arr = []; 14 | readRoot(root, function(v) { 15 | arr.push(v); 16 | }); 17 | arr.slice(0, k); 18 | return arr[k - 1]; 19 | }; -------------------------------------------------------------------------------- /Algorithms/2312的幂power-of-two/power-of-two.js: -------------------------------------------------------------------------------- 1 | /* leetcode 2312的幂power-of-two JavaScript实现 */ 2 | 3 | /** * @param {number} n * @return {boolean} */ 4 | var isPowerOfTwo = function(n) { 5 | if (n < 1) { 6 | return false; 7 | } 8 | if (n == 1) { 9 | return true; 10 | } 11 | do { 12 | if (n % 2 != 0) { 13 | return false; 14 | } 15 | n = n / 2; 16 | } while (n >= 2) return true; 17 | }; -------------------------------------------------------------------------------- /Algorithms/235二叉搜索树的最近公共祖先lowest-common-ancestor-of-a-binary-search-tree/lowest-common-ancestor-of-a-binary-search-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 235二叉搜索树的最近公共祖先lowest-common-ancestor-of-a-binary-search-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @param {TreeNode} p * @param {TreeNode} q * @return {TreeNode} */ 4 | var lowestCommonAncestor = function(root, p, q) { 5 | var pVal = p.val; 6 | var qVal = q.val; 7 | var checkNode = root; 8 | var res = root; 9 | while (true) { 10 | var rootVal = checkNode.val; 11 | if (pVal == rootVal || qVal == rootVal) { 12 | return checkNode; 13 | } else if (pVal < rootVal && qVal < rootVal && checkNode.left) { 14 | res = checkNode; 15 | checkNode = checkNode.left; 16 | } else if (pVal > rootVal && qVal > rootVal && checkNode.right) { 17 | res = checkNode; 18 | checkNode = checkNode.right; 19 | } else if ((pVal > rootVal && qVal < rootVal) || (pVal < rootVal && qVal > rootVal)) { 20 | return checkNode; 21 | } else { 22 | return res; 23 | } 24 | } 25 | }; -------------------------------------------------------------------------------- /Algorithms/236二叉树的最近公共祖先lowest-common-ancestor-of-a-binary-tree/lowest-common-ancestor-of-a-binary-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 236二叉树的最近公共祖先lowest-common-ancestor-of-a-binary-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @param {TreeNode} p * @param {TreeNode} q * @return {TreeNode} */ 4 | var lowestCommonAncestor = function(root, p, q) { 5 | var checkArr = [root]; 6 | var resArr = []; 7 | outWhile: while (checkArr.length > 0) { 8 | var newCheckArr = []; 9 | for (var i = 0; i < checkArr.length; i++) { 10 | var item = checkArr[i]; /* 满足了同级的后面的就不遍历了。*/ 11 | if (hasChild(item, p) && hasChild(item, q)) { 12 | resArr.push(item); 13 | if (item.left) { 14 | newCheckArr.push(item.left); 15 | } 16 | if (item.right) { 17 | newCheckArr.push(item.right); 18 | } 19 | checkArr = newCheckArr; 20 | continue outWhile; 21 | } 22 | } /* 走到这里说明这个层级都没有符合的了。结束查找。*/ 23 | checkArr = []; 24 | } 25 | return resArr[resArr.length - 1]; /* 检查某个节点是否在某个root下面。*/ 26 | function hasChild(root, node) { 27 | var checkArr = [root]; 28 | while (checkArr.length > 0) { 29 | var newCheckArr = []; 30 | for (var i = 0; i < checkArr.length; i++) { 31 | var item = checkArr[i]; 32 | if (node == item) { 33 | return true; 34 | } 35 | if (item.left) { 36 | newCheckArr.push(item.left); 37 | } 38 | if (item.right) { 39 | newCheckArr.push(item.right); 40 | } 41 | } 42 | checkArr = newCheckArr; 43 | } 44 | return false; 45 | } 46 | }; -------------------------------------------------------------------------------- /Algorithms/242有效的字母异位词valid-anagram/valid-anagram.js: -------------------------------------------------------------------------------- 1 | /* leetcode 242有效的字母异位词valid-anagram JavaScript实现 */ 2 | 3 | /** * @param {string} s * @param {string} t * @return {boolean} */ 4 | var isAnagram = function(s, t) { 5 | return s.split('').sort().join('') == t.split('').sort().join(''); 6 | }; -------------------------------------------------------------------------------- /Algorithms/257二叉树的所有路径binary-tree-paths/binary-tree-paths.js: -------------------------------------------------------------------------------- 1 | /* leetcode 257二叉树的所有路径binary-tree-paths JavaScript实现 */ 2 | 3 | /*递归的时候把上一级的path和结论的arr传入。*/ 4 | var binaryTreePaths = function(root, path, arr) { 5 | if (!root) { 6 | return []; 7 | } 8 | if (!arr) { 9 | arr = []; 10 | } 11 | var val = root.val.toString(); 12 | path = path ? path + '->' + val : val; 13 | if (!root.left && !root.right) { 14 | arr.push(path); 15 | } else { 16 | root.left && binaryTreePaths(root.left, path, arr); 17 | root.right && binaryTreePaths(root.right, path, arr); 18 | } 19 | return arr; 20 | } -------------------------------------------------------------------------------- /Algorithms/260只出现一次的数字 IIIsingle-number-iii/single-number-iii.js: -------------------------------------------------------------------------------- 1 | /* leetcode 260只出现一次的数字 IIIsingle-number-iii JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @return {number[]} */ 4 | var singleNumber = function(nums) { 5 | var cache = {}; 6 | var item; 7 | for (var i = 0; i < nums.length; i++) { 8 | item = nums[i]; 9 | if (cache[item] == undefined) { 10 | cache[item] = 0 11 | } 12 | cache[item]++; 13 | if (cache[item] == 2) { 14 | delete cache[item]; 15 | } 16 | } 17 | var keys = Object.keys(cache); 18 | var res = [parseInt(keys[0]), parseInt(keys[1])]; 19 | return res 20 | }; -------------------------------------------------------------------------------- /Algorithms/268缺失数字missing-number/missing-number.js: -------------------------------------------------------------------------------- 1 | /* leetcode 268缺失数字missing-number JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @return {number} */ 4 | var missingNumber = function(nums) { 5 | var resArr = []; 6 | for (var i = 0; i < nums.length; i++) { 7 | var v = nums[i]; 8 | var toPush = ''; 9 | if (nums.indexOf(v - 1) < 0) { 10 | toPush = v - 1; /* 如果然已经有了这个数。说明我们要找的就是这个数*/ 11 | if (resArr.indexOf(toPush) > -1) { 12 | return toPush 13 | } 14 | resArr.push(toPush) 15 | } 16 | if (nums.indexOf(v + 1) < 0) { 17 | toPush = v + 1; 18 | if (resArr.indexOf(toPush) > -1) { 19 | return toPush 20 | } 21 | resArr.push(toPush) 22 | } 23 | } 24 | if (resArr[0] < resArr[1]) { 25 | var min = resArr[0]; 26 | var max = resArr[1]; 27 | } else { 28 | var min = resArr[1]; 29 | var max = resArr[0]; 30 | } 31 | if (min == 0) { 32 | return min; 33 | } else { 34 | return max; 35 | } 36 | }; -------------------------------------------------------------------------------- /Algorithms/283移动零move-zeroes/move-zeroes.js: -------------------------------------------------------------------------------- 1 | /* leetcode 283移动零move-zeroes JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @return {void} Do not return anything, modify nums in-place instead. */ 4 | var moveZeroes = function(nums) { 5 | var zeroCount = 0; 6 | for (var i = 0; i < nums.length - zeroCount;) { 7 | item = nums[i]; 8 | if (item == 0) { 9 | nums.push(0); 10 | nums.splice(i, 1); 11 | zeroCount++; 12 | } else { 13 | i++; 14 | } 15 | } 16 | }; -------------------------------------------------------------------------------- /Algorithms/290单词模式word-pattern/word-pattern.js: -------------------------------------------------------------------------------- 1 | /* leetcode 290单词模式word-pattern JavaScript实现 */ 2 | 3 | /** * @param {string} pattern * @param {string} str * @return {boolean} */ 4 | var wordPattern = function(pattern, str) { 5 | var pArr = pattern.split(''); 6 | var sArr = str.split(' '); 7 | var pLen = pArr.length; 8 | var sLen = sArr.length; 9 | if (pLen != sLen) { 10 | return false; 11 | } 12 | var pObj = {}; 13 | var sObj = {}; 14 | for (var i = 0; i < pLen; i++) { 15 | var pItem = pArr[i]; 16 | var sItem = sArr[i]; /* 要么两个都有,要么两个都没有。*/ 17 | if (!pObj[pItem] && !sObj[sItem]) { 18 | pObj[pItem] = sItem; 19 | sObj[sItem] = pItem; 20 | } else if (!pObj[pItem] || !sObj[sItem]) { /* 如果一个有,另一个没有,说明不匹配*/ 21 | return false; 22 | } else if (pObj[pItem] != sItem || sObj[sItem] != pItem) { 23 | return false; 24 | } 25 | } 26 | return true; 27 | }; -------------------------------------------------------------------------------- /Algorithms/292Nim游戏nim-game/nim-game.js: -------------------------------------------------------------------------------- 1 | /* leetcode 292Nim游戏nim-game JavaScript实现 */ 2 | 3 | /** * @param {number} n * @return {boolean} */ 4 | var canWinNim = function(n) { 5 | var first = n % 4; /* 第一把拿了,剩下的如果是4的位数就稳赢了。*/ 6 | if (0 < first && first < 4) { 7 | return true; 8 | } 9 | return false; 10 | }; -------------------------------------------------------------------------------- /Algorithms/297二叉树的序列化与反序列化serialize-and-deserialize-binary-tree/serialize-and-deserialize-binary-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 297二叉树的序列化与反序列化serialize-and-deserialize-binary-tree JavaScript实现 */ 2 | 3 | /*只要有一个节点不为空,那么一定要有它的左右节点。*/ 4 | var serialize = function(root) { 5 | if (root == null) { 6 | return '[]'; 7 | } 8 | var checkArr = [root]; 9 | var resArr = [root.val]; 10 | while (checkArr.length > 0) { 11 | var newCheckArr = []; 12 | for (var i = 0; i < checkArr.length; i++) { 13 | var item = checkArr[i]; 14 | if (item.left) { 15 | newCheckArr.push(item.left); 16 | resArr.push(item.left.val); 17 | } else { 18 | resArr.push(null); 19 | } 20 | if (item.right) { 21 | newCheckArr.push(item.right); 22 | resArr.push(item.right.val); 23 | } else { 24 | resArr.push(null); 25 | } 26 | } 27 | checkArr = newCheckArr; 28 | } 29 | return JSON.stringify(resArr); 30 | }; /** * Decodes your encoded data to tree. * * @param {string} data * @return {TreeNode} */ 31 | var deserialize = function(data) { 32 | if (data == '[]') { 33 | return null; 34 | } 35 | var arr = JSON.parse(data); 36 | var len = arr.length; 37 | var root = new TreeNode(arr.shift()); 38 | var nextArr = [root]; 39 | while (arr.length > 0) { 40 | var newCheckArr = []; 41 | for (var i = 0; i < nextArr.length; i++) { 42 | var item = nextArr[i]; 43 | var arrItem1 = arr.shift(); 44 | if (arrItem1 == 'null' || arrItem1 == null) { 45 | item.left = null; 46 | } else { 47 | item.left = new TreeNode(arrItem1); 48 | newCheckArr.push(item.left); 49 | } 50 | var arrItem2 = arr.shift(); 51 | if (arrItem2 == 'null' || arrItem2 == null) { 52 | item.right = null; 53 | } else { 54 | item.right = new TreeNode(arrItem2); 55 | newCheckArr.push(item.right); 56 | } 57 | } 58 | nextArr = newCheckArr; 59 | } 60 | return root; 61 | }; /** * Your functions will be called as such: * deserialize(serialize(root)); */ -------------------------------------------------------------------------------- /Algorithms/303区域和检索 - 数组不可变range-sum-query-immutable/range-sum-query-immutable.js: -------------------------------------------------------------------------------- 1 | /* leetcode 303区域和检索 - 数组不可变range-sum-query-immutable JavaScript实现 */ 2 | 3 | /*动态规划。保存一个数组,包含所有位的和。这样只是初始化的时候慢。但是后面的sumRange就很快了。*/ 4 | var NumArray = function(nums) { 5 | this.sums = []; 6 | var sums = this.sums; 7 | if (nums.length > 0) { 8 | sums[0] = nums[0]; 9 | for (var i = 1; i <= nums.length; i++) { 10 | sums[i] = sums[i - 1] + nums[i]; 11 | } 12 | } 13 | }; 14 | NumArray.prototype.sumRange = function(i, j) { 15 | var sums = this.sums; 16 | if (i == 0) { 17 | return sums[j]; 18 | } else { 19 | return sums[j] - sums[i - 1]; 20 | } 21 | }; -------------------------------------------------------------------------------- /Algorithms/3263的幂power-of-three/power-of-three.js: -------------------------------------------------------------------------------- 1 | /* leetcode 3263的幂power-of-three JavaScript实现 */ 2 | 3 | /** * @param {number} n * @return {boolean} */ /*不用循环怎么做*/ 4 | var isPowerOfThree = function(n) { 5 | if (n < 1) { 6 | return false; 7 | } 8 | while (n >= 3) { 9 | if (n % 3 != 0) { 10 | return false; 11 | } 12 | n = n / 3; 13 | } 14 | if (n == 1) { 15 | return true; 16 | } else { 17 | return false; 18 | } 19 | }; -------------------------------------------------------------------------------- /Algorithms/3424的幂power-of-four/power-of-four.js: -------------------------------------------------------------------------------- 1 | /* leetcode 3424的幂power-of-four JavaScript实现 */ 2 | 3 | /** * @param {number} num * @return {boolean} */ 4 | var isPowerOfFour = function(n) { 5 | if (n < 1) { 6 | return false; 7 | } 8 | while (n >= 4) { 9 | if (n % 4 != 0) { 10 | return false; 11 | } 12 | n = n / 4; 13 | } 14 | if (n == 1) { 15 | return true; 16 | } else { 17 | return false; 18 | } 19 | }; -------------------------------------------------------------------------------- /Algorithms/344反转字符串reverse-string/reverse-string.js: -------------------------------------------------------------------------------- 1 | /* leetcode 344反转字符串reverse-string JavaScript实现 */ 2 | 3 | /** * @param {string} s * @return {string} */ 4 | var reverseString = function(s) { 5 | return s.split('').reverse().join(''); 6 | }; -------------------------------------------------------------------------------- /Algorithms/345反转字符串中的元音字母reverse-vowels-of-a-string/reverse-vowels-of-a-string.js: -------------------------------------------------------------------------------- 1 | /* leetcode 345反转字符串中的元音字母reverse-vowels-of-a-string JavaScript实现 */ 2 | 3 | /** * @param {string} s * @return {string} */ /*把元音匹配出来翻转一下,再遍历数组,遇到元音就取第一个匹配给它。*/ 4 | var reverseVowels = function(s) { 5 | if (s == undefined || s == '') { 6 | return ''; 7 | } 8 | var reg = /[aeiouAEIOU]/g; 9 | var match = s.match(reg); 10 | if (!match) { 11 | return s; 12 | } 13 | var reverseMathcArr = match.reverse(); 14 | var sArr = s.split(''); 15 | for (var i = 0; i < sArr.length; i++) { 16 | var item = sArr[i]; 17 | if (item.match(reg)) { 18 | sArr[i] = reverseMathcArr.shift(); 19 | } 20 | } 21 | return sArr.join(''); 22 | }; -------------------------------------------------------------------------------- /Algorithms/349两个数组的交集intersection-of-two-arrays/intersection-of-two-arrays.js: -------------------------------------------------------------------------------- 1 | /* leetcode 349两个数组的交集intersection-of-two-arrays JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums1 * @param {number[]} nums2 * @return {number[]} */ 4 | var intersection = function(nums1, nums2) { 5 | var res = []; 6 | for (var i = 0; i < nums1.length; i++) { 7 | var item = nums1[i]; 8 | if (nums2.indexOf(item) > -1 && res.indexOf(item) < 0) { 9 | res.push(item); 10 | } 11 | } 12 | return res; 13 | }; -------------------------------------------------------------------------------- /Algorithms/350两个数组的交集 IIintersection-of-two-arrays-ii/intersection-of-two-arrays-ii.js: -------------------------------------------------------------------------------- 1 | /* leetcode 350两个数组的交集 IIintersection-of-two-arrays-ii JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums1 * @param {number[]} nums2 * @return {number[]} */ 4 | var intersect = function(nums1, nums2) { 5 | var res = []; 6 | var numObj1 = {}; 7 | var numObj2 = {}; 8 | var numLen1 = nums1.length, 9 | numLen2 = nums2.length; 10 | for (var i = 0; i < numLen1; i++) { 11 | var item1 = nums1[i]; 12 | if (nums2.indexOf(item1) > -1) { 13 | if (!numObj1[item1]) { 14 | numObj1[item1] = 0; 15 | } 16 | numObj1[item1]++; 17 | } 18 | } 19 | for (var j = 0; j < numLen2; j++) { 20 | var item2 = nums2[j]; 21 | if (numObj1[item2]) { 22 | if (!numObj2[item2]) { 23 | numObj2[item2] = 0; 24 | } 25 | numObj2[item2]++; 26 | } 27 | } 28 | for (var k in numObj1) { 29 | var min = Math.min(numObj1[k], numObj2[k]); 30 | while (min--) { 31 | res.push(Number(k)); 32 | } 33 | } 34 | return res; 35 | }; -------------------------------------------------------------------------------- /Algorithms/367有效的完全平方数valid-perfect-square/valid-perfect-square.js: -------------------------------------------------------------------------------- 1 | /* leetcode 367有效的完全平方数valid-perfect-square JavaScript实现 */ 2 | 3 | /** * @param {number} num * @return {boolean} */ 4 | var isPerfectSquare = function(num) { 5 | if (num == 0) { 6 | return true; 7 | } 8 | var i = 1; 9 | while (i <= num) { 10 | if (num / i == i) { 11 | return true; 12 | } 13 | i++; 14 | } 15 | return false; 16 | }; -------------------------------------------------------------------------------- /Algorithms/371两整数之和sum-of-two-integers/sum-of-two-integers.js: -------------------------------------------------------------------------------- 1 | /* leetcode 371两整数之和sum-of-two-integers JavaScript实现 */ 2 | 3 | /** * @param {number} a * @param {number} b * @return {number} */ /*这个方法真的是。。。没啥用啊。生成两个数组,连起来,求长度。*/ /* 如果有负数的情况需要用eval把拼出来的字符串求值。*/ 4 | var getSum = function(a, b) { 5 | if (a >= 0 && b >= 0) { 6 | var arrA = new Array(a); 7 | var arrB = new Array(b); 8 | var arrC = arrA.concat(arrB); 9 | return arrC.length; 10 | } else if (a < 0) { 11 | return eval([b, a].join('')) 12 | } else { 13 | return eval([a, b].join('')) 14 | } 15 | }; -------------------------------------------------------------------------------- /Algorithms/387字符串中的第一个唯一字符first-unique-character-in-a-string/first-unique-character-in-a-string.js: -------------------------------------------------------------------------------- 1 | /* leetcode 387字符串中的第一个唯一字符first-unique-character-in-a-string JavaScript实现 */ 2 | 3 | /** * @param {string} s * @return {number} */ 4 | var firstUniqChar = function(s) { 5 | var sArr = s.split(''); 6 | for (var i = 0; i < sArr.length; i++) { 7 | var item = sArr[i]; 8 | if (sArr.indexOf(item) == sArr.lastIndexOf(item)) { 9 | return i; 10 | } 11 | } 12 | return -1; 13 | }; -------------------------------------------------------------------------------- /Algorithms/389找不同find-the-difference/find-the-difference.js: -------------------------------------------------------------------------------- 1 | /* leetcode 389找不同find-the-difference JavaScript实现 */ 2 | 3 | /** * @param {string} s * @param {string} t * @return {character} */ 4 | var findTheDifference = function(s, t) { 5 | var s1 = s.split('').sort(); 6 | var t1 = t.split('').sort(); /* 先排序。找出第一个不一样的。*/ 7 | for (var i = 0; i < s.length; i++) { 8 | if (s1[i] != t1[i]) { 9 | return t1[i]; 10 | } 11 | } 12 | return t1[t1.length - 1] 13 | }; -------------------------------------------------------------------------------- /Algorithms/404左叶子之和sum-of-left-leaves/sum-of-left-leaves.js: -------------------------------------------------------------------------------- 1 | /* leetcode 404左叶子之和sum-of-left-leaves JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number} */ 4 | var sumOfLeftLeaves = function(root) { 5 | if (root == null) { 6 | return 0; 7 | } 8 | var sum = 0; 9 | var left = root.left; 10 | var right = root.right; /* 没有叶子的才是叶子。*/ 11 | if (left != null && left.left == null && left.right == null) { 12 | sum = sum + left.val + sumOfLeftLeaves(right); 13 | } else { 14 | sum = sum + sumOfLeftLeaves(left) + sumOfLeftLeaves(right); 15 | } 16 | return sum; 17 | }; -------------------------------------------------------------------------------- /Algorithms/409最长回文串longest-palindrome/longest-palindrome.js: -------------------------------------------------------------------------------- 1 | /* leetcode 409最长回文串longest-palindrome JavaScript实现 */ 2 | 3 | /** * @param {string} s * @return {number} */ 4 | var longestPalindrome = function(s) { 5 | if (s.length == 0) { 6 | return 0; 7 | } 8 | var sArr = s.split(''); 9 | var cacheObj = {}; 10 | var res = 0; /* 先计算出每一个字母有几个。*/ /* 有2个的先扣掉给结果。*/ /* 剩下的就都是单数的。*/ 11 | sArr.forEach(function(v, i) { 12 | if (cacheObj[v] == undefined) { 13 | cacheObj[v] = 0; 14 | } 15 | cacheObj[v]++; 16 | if (cacheObj[v] == 2) { 17 | res += 2; 18 | delete cacheObj[v]; 19 | } 20 | }); /* 如果对象中有值,说明还有单数的,最多可以利用一个。*/ 21 | if (JSON.stringify(cacheObj) != "{}") { 22 | res++; 23 | } 24 | return res; 25 | }; -------------------------------------------------------------------------------- /Algorithms/434字符串中的单词数number-of-segments-in-a-string/number-of-segments-in-a-string.js: -------------------------------------------------------------------------------- 1 | /* leetcode 434字符串中的单词数number-of-segments-in-a-string JavaScript实现 */ 2 | 3 | /** * @param {string} s * @return {number} */ 4 | var countSegments = function(s) { 5 | s = s.trim(); 6 | if ('' == s) { 7 | return 0; 8 | } 9 | var sArr = s.split(/\s+/); 10 | return sArr.length; 11 | }; -------------------------------------------------------------------------------- /Algorithms/437路径总和 IIIpath-sum-iii/path-sum-iii.js: -------------------------------------------------------------------------------- 1 | /* leetcode 437路径总和 IIIpath-sum-iii JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @param {number} sum * @return {number} */ 4 | var pathSum = function(root, sum) { 5 | var count = 0; /* 递归的时候把上一级的path传入。*/ 6 | var binaryTreePaths = function(root, path) { 7 | if (!root) { 8 | return; 9 | } 10 | var val = root.val; 11 | path = path ? path + '->' + val : val.toString(); /* 翻转处理一下,从最后一个往前加。*/ 12 | var resPath = path.split('->').map(function(v) { 13 | return Number(v); 14 | }).reverse(); 15 | resPath.reduce(function(a, b) { 16 | var inSum = a + b; /* 这个迭加。中间有值一样的,也加上。*/ 17 | if (inSum == sum) { 18 | count++; 19 | } 20 | return inSum; 21 | }, 0); 22 | root.left && binaryTreePaths(root.left, path); 23 | root.right && binaryTreePaths(root.right, path); 24 | } 25 | binaryTreePaths(root); 26 | return count; 27 | }; -------------------------------------------------------------------------------- /Algorithms/442数组中重复的数据find-all-duplicates-in-an-array/find-all-duplicates-in-an-array.js: -------------------------------------------------------------------------------- 1 | /* leetcode 442数组中重复的数据find-all-duplicates-in-an-array JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @return {number[]} */ 4 | var findDuplicates = function(nums) { /* 长度*/ 5 | var len = nums.length; /* 生成一个每个值为0的数组。长度为数组长度。*/ 6 | let res = (new Array(len + 1)).join('0').split(''); 7 | for (var i = 0; i < len; i++) { 8 | var item = nums[i]; /* 用-1;因为如果+1的话遇到真正的1,2时过滤会出错*/ 9 | res[item - 1] = parseInt(res[item - 1]) - 1; 10 | if (res[item - 1] === -2) { 11 | res[item - 1] = item; 12 | } 13 | } 14 | return res.filter(function(v, i) { 15 | return v != '0' && v != -1; 16 | }); 17 | }; -------------------------------------------------------------------------------- /Algorithms/448找到所有数组中消失的数字find-all-numbers-disappeared-in-an-array/find-all-numbers-disappeared-in-an-array.js: -------------------------------------------------------------------------------- 1 | /* leetcode 448找到所有数组中消失的数字find-all-numbers-disappeared-in-an-array JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @return {number[]} */ 4 | var findDisappearedNumbers = function(nums) { 5 | var len = nums.length; /* 不用循环生成数组0到n*/ 6 | let res = [...(new Array(len + 1)).keys()]; 7 | res.splice(0, 1); 8 | for (var i = 0; i < len; i++) { 9 | var item = nums[i]; 10 | if (res[item - 1]) { 11 | res[item - 1] = 0; 12 | } 13 | } 14 | return res.filter(function(v, i) { 15 | return v != 0; 16 | }); 17 | }; -------------------------------------------------------------------------------- /Algorithms/450删除二叉搜索树中的节点delete-node-in-a-bst/delete-node-in-a-bst.js: -------------------------------------------------------------------------------- 1 | /* leetcode 450删除二叉搜索树中的节点delete-node-in-a-bst JavaScript实现 */ 2 | 3 | function deleteNode(root, key) { 4 | if (!root) { 5 | return root; 6 | } 7 | var val = root.val; 8 | if (key < val) { 9 | root.left = deleteNode(root.left, key); 10 | return root; 11 | } else if (key > val) { 12 | root.right = deleteNode(root.right, key); 13 | return root; 14 | } else { 15 | if (root.left == null && root.right == null) { 16 | root = null; 17 | return root; 18 | } 19 | if (root.left == null) { 20 | root = root.right; 21 | return root; 22 | } 23 | if (root.right == null) { 24 | root = root.left; 25 | return root; 26 | } 27 | var aux = findMinNode(root.right); 28 | root.val = aux; 29 | root.right = deleteNode(root.right, aux); 30 | return root; 31 | } 32 | 33 | function findMinNode(root) { 34 | if (!root) { 35 | return null; 36 | } 37 | var minNode = root; 38 | while (minNode.left) { 39 | minNode = minNode.left; 40 | } 41 | return minNode.val; 42 | } 43 | } -------------------------------------------------------------------------------- /Algorithms/451根据字符出现频率排序sort-characters-by-frequency/sort-characters-by-frequency.js: -------------------------------------------------------------------------------- 1 | /* leetcode 451根据字符出现频率排序sort-characters-by-frequency JavaScript实现 */ 2 | 3 | /** * @param {string} s * @return {string} */ 4 | var frequencySort = function(s) { 5 | var sArr = s.split(''); 6 | var map = {}; /* 统计*/ 7 | for (var i = 0; i < sArr.length; i++) { 8 | var item = sArr[i]; 9 | if (!map[item]) { 10 | map[item] = 0; 11 | } 12 | map[item]++; 13 | } /* 转成数组*/ 14 | var arr = []; 15 | for (var i in map) { 16 | if (!map.hasOwnProperty(i)) { 17 | continue; 18 | } 19 | arr.push([ 20 | [i], map[i] 21 | ]); 22 | } /* 排序*/ 23 | var resArr = arr.sort(function(a, b) { 24 | return b[1] - a[1]; 25 | }); /* 生成字符串*/ 26 | var res = ''; 27 | resArr.forEach(function(v, k) { 28 | res = res + new Array(v[1] + 1).join(v[0]); 29 | }); 30 | return res; 31 | }; -------------------------------------------------------------------------------- /Algorithms/459重复的子字符串repeated-substring-pattern/repeated-substring-pattern.js: -------------------------------------------------------------------------------- 1 | /* leetcode 459重复的子字符串repeated-substring-pattern JavaScript实现 */ 2 | 3 | /** * @param {string} s * @return {boolean} */ 4 | var repeatedSubstringPattern = function(s) { 5 | var strLen = s.length; 6 | for (var i = 0; i < strLen; i++) { 7 | var item = s.slice(0, i); 8 | var len = item.length; /* 除不尽则跳过。*/ 9 | if (strLen % len != 0) { 10 | continue; 11 | } 12 | var n = strLen / len; /* 字符串乘法*/ 13 | var joinStr = new Array(n + 1).join(item); 14 | if (joinStr == s) { 15 | return true; 16 | } 17 | } 18 | return false; 19 | }; -------------------------------------------------------------------------------- /Algorithms/485最大连续1的个数max-consecutive-ones/max-consecutive-ones.js: -------------------------------------------------------------------------------- 1 | /* leetcode 485最大连续1的个数max-consecutive-ones JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @return {number} */ 4 | var findMaxConsecutiveOnes = function(nums) { 5 | var numsStr = nums.join(''); /* 正则匹配1。判断最长的匹配。*/ 6 | var reg = /1+/g; 7 | var match = numsStr.match(reg); 8 | var max = 0; 9 | if (!match) { 10 | return max; 11 | } 12 | match.forEach(function(v, i) { 13 | if (v.length > max) { 14 | max = v.length; 15 | } 16 | }); 17 | return max; 18 | }; -------------------------------------------------------------------------------- /Algorithms/500键盘行keyboard-row/keyboard-row.js: -------------------------------------------------------------------------------- 1 | /* leetcode 500键盘行keyboard-row JavaScript实现 */ 2 | 3 | /** * @param {string[]} words * @return {string[]} */ /*判断每个匹配的数量与字符串长度。*/ 4 | var findWords = function(words) { 5 | var res = []; 6 | var reg1 = /[qwertyuiopQWERTYUIOP]/g; 7 | var reg2 = /[asdfghjklASDFGHJKL]/g; 8 | var reg3 = /[zxcvbnmZXCVBNM]/g; 9 | var regArr = [reg1, reg2, reg3]; 10 | words.forEach(function(word) { 11 | for (var i = 0; i < regArr.length; i++) { 12 | var match = word.match(regArr[i]); 13 | if (match) { 14 | if (match.length != word.length) { 15 | return; 16 | } 17 | } 18 | } 19 | res.push(word); 20 | }); 21 | return res; 22 | }; -------------------------------------------------------------------------------- /Algorithms/507完美数perfect-number/perfect-number.js: -------------------------------------------------------------------------------- 1 | /* leetcode 507完美数perfect-number JavaScript实现 */ 2 | 3 | /** * @param {number} num * @return {boolean} */ 4 | var checkPerfectNumber = function(num) { 5 | if (num == 0) { 6 | return false; 7 | } 8 | var res = 0; 9 | var numArr = []; 10 | var i = 1; 11 | while (i < num) { 12 | if (num % i == 0) { 13 | res += i; 14 | } 15 | i++; 16 | } 17 | if (res == num) { 18 | return true; 19 | } 20 | return false; 21 | }; -------------------------------------------------------------------------------- /Algorithms/513找树左下角的值find-bottom-left-tree-value/find-bottom-left-tree-value.js: -------------------------------------------------------------------------------- 1 | /* leetcode 513找树左下角的值find-bottom-left-tree-value JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number} */ 4 | var findBottomLeftValue = function(root) { 5 | if (root == null) { 6 | return null; 7 | } 8 | var checkArr = [root]; 9 | while (checkArr.length > 0) { 10 | var newCheckArr = []; 11 | var leftValue = checkArr[0].val; 12 | for (var i = 0; i < checkArr.length; i++) { 13 | var item = checkArr[i]; 14 | if (item.left) { 15 | newCheckArr.push(item.left); 16 | } 17 | if (item.right) { 18 | newCheckArr.push(item.right); 19 | } 20 | } 21 | checkArr = newCheckArr; 22 | } 23 | return leftValue; 24 | }; -------------------------------------------------------------------------------- /Algorithms/515在每个树行中找最大值find-largest-value-in-each-tree-row/find-largest-value-in-each-tree-row.js: -------------------------------------------------------------------------------- 1 | /* leetcode 515在每个树行中找最大值find-largest-value-in-each-tree-row JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number[]} */ 4 | var largestValues = function(root) { 5 | if (root == null) { 6 | return []; 7 | } 8 | var checkArr = [root]; 9 | var resArr = [root.val]; 10 | while (checkArr.length > 0) { 11 | var newCheckArr = []; 12 | for (var i = 0; i < checkArr.length; i++) { 13 | var item = checkArr[i]; 14 | if (item.left) { 15 | newCheckArr.push(item.left); 16 | } 17 | if (item.right) { 18 | newCheckArr.push(item.right); 19 | } 20 | } 21 | checkArr = newCheckArr; 22 | if (checkArr.length > 0) { 23 | var levelArr = checkArr.map(function(v, i) { 24 | return v.val; 25 | }); 26 | resArr.push(Math.max.apply(Math, levelArr)); 27 | } 28 | } 29 | return resArr; 30 | }; -------------------------------------------------------------------------------- /Algorithms/520检测大写字母detect-capital/detect-capital.js: -------------------------------------------------------------------------------- 1 | /* leetcode 520检测大写字母detect-capital JavaScript实现 */ 2 | 3 | /** * @param {string} word * @return {boolean} */ 4 | var detectCapitalUse = function(word) { 5 | var bigReg = /[A-Z]+/g; 6 | var smallReg = /[a-z]+/g; 7 | var wordLen = word.length; 8 | 9 | function match(word, reg) { 10 | if (word == '') { 11 | return true; 12 | } 13 | var len = word.length; 14 | var match = word.match(reg); 15 | if (match && match[0].length == len) { 16 | return true; 17 | } 18 | return false; 19 | } 20 | if (match(word, bigReg) || match(word, smallReg)) { 21 | return true; 22 | } 23 | if (match(word.slice(0, 1), bigReg) && match(word.slice(1), smallReg)) { 24 | return true; 25 | } 26 | return false; 27 | }; -------------------------------------------------------------------------------- /Algorithms/543二叉树的直径diameter-of-binary-tree/diameter-of-binary-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 543二叉树的直径diameter-of-binary-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number} */ 4 | var diameterOfBinaryTree = function(root) { 5 | var max = 0; /* 核心思想是计算每个节点左右高度和。加起来就是这个节点下的最大路径。假设每个最长路径都要经过一个根节点。*/ 6 | function check(root) { 7 | if (!root) { 8 | return 0; 9 | } 10 | var val = root.val; 11 | var left = root.left; 12 | var right = root.right; 13 | var sum = nodeHeight(root.left) + nodeHeight(root.right); 14 | if (sum > max) { 15 | max = sum; 16 | } 17 | check(root.left); 18 | check(root.right); 19 | } /* 计算每个节点的高度。*/ 20 | function nodeHeight(root) { 21 | if (!root) { 22 | return 0; 23 | } 24 | return Math.max(nodeHeight(root.left), nodeHeight(root.right)) + 1; 25 | } 26 | check(root); 27 | return max; 28 | }; -------------------------------------------------------------------------------- /Algorithms/557反转字符串中的单词 IIIreverse-words-in-a-string-iii/reverse-words-in-a-string-iii.js: -------------------------------------------------------------------------------- 1 | /* leetcode 557反转字符串中的单词 IIIreverse-words-in-a-string-iii JavaScript实现 */ 2 | 3 | /** * @param {string} s * @return {string} */ 4 | var reverseWords = function(s) { 5 | var sArr = s.split(' '); 6 | var resArr = sArr.map(function(s) { 7 | return s.split('').reverse().join(''); 8 | }); 9 | return resArr.join(' '); 10 | }; -------------------------------------------------------------------------------- /Algorithms/561数组拆分 Iarray-partition-i/array-partition-i.js: -------------------------------------------------------------------------------- 1 | /* leetcode 561数组拆分 Iarray-partition-i JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @return {number} */ /* 先排个序。然后依次取双数序号index的。*/ /* 注意sort排序内部并不完全是按大小的。[6214, -2290, 2833, -7908]。所以需要加逻辑。*/ 4 | var arrayPairSum = function(nums) { /* 这里要是a-b。不能是ab,a-b>0。[11, 41, -9046, 2047, 1118, 8477, 8446, 279, 4925, 7380, -1719, 3855]有点奇怪。要再看一下。*/ 5 | nums.sort(function(a, b) { 6 | return a - b; 7 | }); 8 | var sum = 0; 9 | var len = nums.length; 10 | for (var i = 0; i < len; i = i + 2) { 11 | sum += nums[i]; 12 | } 13 | return sum; 14 | }; -------------------------------------------------------------------------------- /Algorithms/563二叉树的坡度binary-tree-tilt/binary-tree-tilt.js: -------------------------------------------------------------------------------- 1 | /* leetcode 563二叉树的坡度binary-tree-tilt JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number} */ 4 | var findTilt = function(root) { /* 求node和。*/ 5 | function nodeSum(root) { 6 | if (!root) { 7 | return 0; 8 | } 9 | return nodeSum(root.left) + nodeSum(root.right) + root.val; 10 | } /* 求某一个节点的坡度*/ 11 | function nodeTilt(root) { 12 | return Math.abs(nodeSum(root.left) - nodeSum(root.right)); 13 | } 14 | 15 | function find(root) { 16 | if (!root) { 17 | return 0; 18 | } 19 | return nodeTilt(root) + find(root.left) + find(root.right); 20 | } 21 | return find(root); 22 | }; -------------------------------------------------------------------------------- /Algorithms/572另一个树的子树subtree-of-another-tree/subtree-of-another-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 572另一个树的子树subtree-of-another-tree JavaScript实现 */ 2 | 3 | /*遍历判断子节点是否跟子树相同。*/ 4 | var isSubtree = function(s, t) { 5 | var isSameTree = function(p, q) { 6 | if (p == null && q != null) { 7 | return false; 8 | } 9 | if (p != null && q == null) { 10 | return false; 11 | } /* 查询到子节点都为null时结束。*/ 12 | if (p == null && q == null) { 13 | return true; 14 | } 15 | if (p.val != q.val) { 16 | return false; 17 | } /* 递归对比左叶与右叶。*/ 18 | return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); 19 | }; 20 | 21 | function check(s, t) { 22 | return isSameTree(s, t) || (s && check(s.left, t)) || (s && check(s.right, t)) || false; 23 | } 24 | return check(s, t); 25 | }; -------------------------------------------------------------------------------- /Algorithms/606根据二叉树创建字符串construct-string-from-binary-tree/construct-string-from-binary-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 606根据二叉树创建字符串construct-string-from-binary-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} t * @return {string} */ 4 | var tree2str = function(t) { 5 | if (!t) { 6 | return ''; 7 | } 8 | if (t.left == null && t.right == null) { 9 | return t.val + ''; 10 | } else if (t.left == null) { 11 | return t.val + '()(' + tree2str(t.right) + ')'; 12 | } else if (t.right == null) { 13 | return t.val + '(' + tree2str(t.left) + ')'; 14 | } else { 15 | return t.val + '(' + tree2str(t.left) + ')(' + tree2str(t.right) + ')'; 16 | } 17 | }; -------------------------------------------------------------------------------- /Algorithms/617合并二叉树merge-two-binary-trees/merge-two-binary-trees.js: -------------------------------------------------------------------------------- 1 | /* leetcode 617合并二叉树merge-two-binary-trees JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ 4 | var mergeTrees = function(t1, t2) { 5 | if (t1 == null) { 6 | return t2; 7 | } 8 | if (t2 == null) { 9 | return t1; 10 | } 11 | t1.val = t1.val + t2.val; 12 | t1.left = mergeTrees(t1.left, t2.left); 13 | t1.right = mergeTrees(t1.right, t2.right); 14 | return t1; 15 | }; -------------------------------------------------------------------------------- /Algorithms/623在二叉树中增加一行add-one-row-to-tree/add-one-row-to-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 623在二叉树中增加一行add-one-row-to-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @param {number} v * @param {number} d * @return {TreeNode} */ 4 | var addOneRow = function(root, v, d) { 5 | if (root == null) { 6 | return []; 7 | } 8 | var checkArr = [root]; 9 | if (d == 1) { 10 | var node = new TreeNode(v); 11 | node.left = root; 12 | return node; 13 | } 14 | var level = 1; 15 | var ok = false; 16 | while (checkArr.length > 0) { 17 | var newCheckArr = []; 18 | for (var i = 0; i < checkArr.length; i++) { 19 | var item = checkArr[i]; 20 | if (level + 1 == d) { 21 | var oriLeft = item.left; 22 | var oriRight = item.right; 23 | item.left = new TreeNode(v); 24 | item.right = new TreeNode(v); 25 | item.left.left = oriLeft; 26 | item.right.right = oriRight; 27 | ok = true; 28 | } else { 29 | if (item.left) { 30 | newCheckArr.push(item.left); 31 | } 32 | if (item.right) { 33 | newCheckArr.push(item.right); 34 | } 35 | } 36 | } 37 | checkArr = newCheckArr; 38 | level++; /* 迭代到对应的位置就直接返回了。*/ 39 | if (ok == true) { 40 | return root; 41 | } 42 | } 43 | return root; 44 | }; -------------------------------------------------------------------------------- /Algorithms/628三个数的最大乘积maximum-product-of-three-numbers/maximum-product-of-three-numbers.js: -------------------------------------------------------------------------------- 1 | /* leetcode 628三个数的最大乘积maximum-product-of-three-numbers JavaScript实现 */ 2 | 3 | /** * @param {number[]} nums * @return {number} */ 4 | var maximumProduct = function(nums) { 5 | var sotedArr = nums.sort(function(a, b) { 6 | return a - b; 7 | }); 8 | var len = nums.length; /* 不大于0的*/ 9 | var smallArr = []; /* 大于0的*/ 10 | var bigArr = []; 11 | for (var i = 0; i < sotedArr.length; i++) { 12 | if (sotedArr[i] <= 0) { 13 | smallArr.push(sotedArr[i]); 14 | } else { 15 | bigArr.push(sotedArr[i]); 16 | } 17 | } /* 负负得正。*/ 18 | var twoRes; 19 | var bigLen = bigArr.length; 20 | var smallLen = smallArr.length; /* 如果全是小于等于0的。*/ 21 | if (bigLen == 0) { 22 | return smallArr[smallLen - 1] * smallArr[smallLen - 2] * smallArr[smallLen - 3]; /* 只有一个大于0的。*/ 23 | } else if (bigLen == 1) { 24 | return smallArr[0] * smallArr[1] * bigArr[0]; /* 后面的都是len大于等于2的。*/ 25 | } else if (bigArr.length > 2 && smallArr.length >= 2) { 26 | var bigRes = bigArr[bigArr.length - 1] * bigArr[bigArr.length - 2]; 27 | var smallRes = smallArr[0] * smallArr[1]; 28 | return Math.max(bigRes * bigArr[bigLen - 3], smallRes * bigArr[bigLen - 1]); /* 为负的情况 */ 29 | } else { 30 | return sotedArr[len - 1] * sotedArr[len - 2] * sotedArr[len - 3] 31 | } 32 | }; -------------------------------------------------------------------------------- /Algorithms/633平方数之和sum-of-square-numbers/sum-of-square-numbers.js: -------------------------------------------------------------------------------- 1 | /* leetcode 633平方数之和sum-of-square-numbers JavaScript实现 */ 2 | 3 | /** * @param {number} c * @return {boolean} */ 4 | var judgeSquareSum = function(c) { 5 | var i = 0; 6 | while (i <= c) { 7 | var afterPow = c - Math.pow(i, 2); 8 | if (afterPow < 0) { 9 | return false; 10 | } 11 | var item = Math.sqrt(afterPow); /* 判断有没有小数部分*/ 12 | if (item % 1 == 0) { 13 | return true; 14 | } 15 | i++; 16 | } 17 | return false; 18 | }; -------------------------------------------------------------------------------- /Algorithms/637二叉树的层平均值average-of-levels-in-binary-tree/average-of-levels-in-binary-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 637二叉树的层平均值average-of-levels-in-binary-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number[]} */ 4 | var averageOfLevels = function(root) { 5 | var checkArr = [root]; 6 | var resArr = [root.val]; 7 | while (checkArr.length > 0) { 8 | var newCheckArr = []; 9 | for (var i = 0; i < checkArr.length; i++) { 10 | var item = checkArr[i]; 11 | if (item.left) { 12 | newCheckArr.push(item.left); 13 | } 14 | if (item.right) { 15 | newCheckArr.push(item.right); 16 | } 17 | } 18 | checkArr = newCheckArr; 19 | if (checkArr.length > 0) { 20 | var sum = checkArr.reduce(function(a, b) { 21 | return a + b.val; 22 | }, 0); 23 | resArr.push(sum / checkArr.length); 24 | } 25 | } 26 | return resArr; 27 | }; -------------------------------------------------------------------------------- /Algorithms/647回文子串palindromic-substrings/palindromic-substrings.js: -------------------------------------------------------------------------------- 1 | /* leetcode 647回文子串palindromic-substrings JavaScript实现 */ 2 | 3 | /*思路一:dp算法。不断加。然后新增一个的时候会在遍历时找前面所有跟当前值一样的值,截取出来看是不是回文。超时。*/ /*思路二。每遍历一个。往前后查询回文。注意查了两次。*/ 4 | var countSubstrings = function(s) { 5 | var sArr = s.split(''); 6 | var len = sArr.length; 7 | var count = 0; 8 | for (var i = 0; i < len; i++) { 9 | check(i, i + 1); 10 | check(i - 1, i + 1); 11 | count++; 12 | } 13 | return count; 14 | 15 | function check(left, right) { 16 | while (s[left] && s[right] && s[left] == s[right]) { 17 | left--; 18 | right++; 19 | count++; 20 | } 21 | } 22 | }; -------------------------------------------------------------------------------- /Algorithms/652寻找重复的子树find-duplicate-subtrees/find-duplicate-subtrees.js: -------------------------------------------------------------------------------- 1 | /* leetcode 652.寻找重复的子树 JavaScript实现 */ 2 | 3 | /*序列化所有节点。以节点为key放到一个对象。如果值为2,就把节点加入到结果中。*/ 4 | var findDuplicateSubtrees = function(root) { 5 | var res = []; 6 | var obj = {}; 7 | var helper = function(root) { 8 | if (!root) { 9 | return ''; 10 | } 11 | var str = serialize(root); 12 | if (obj[str] === undefined) { 13 | obj[str] = 0; 14 | } 15 | obj[str]++; 16 | if (obj[str] == 2) { 17 | res.push(root); 18 | } 19 | root.left && helper(root.left); 20 | root.right && helper(root.right); 21 | } /* 序列化。*/ 22 | var serialize = function(root) { 23 | if (root == null) { 24 | return '[]'; 25 | } 26 | var checkArr = [root]; 27 | var resArr = [root.val]; 28 | while (checkArr.length > 0) { 29 | var newCheckArr = []; 30 | for (var i = 0; i < checkArr.length; i++) { 31 | var item = checkArr[i]; 32 | if (item.left) { 33 | newCheckArr.push(item.left); 34 | resArr.push(item.left.val); 35 | } else { 36 | resArr.push(null); 37 | } 38 | if (item.right) { 39 | newCheckArr.push(item.right); 40 | resArr.push(item.right.val); 41 | } else { 42 | resArr.push(null); 43 | } 44 | } 45 | checkArr = newCheckArr; 46 | } 47 | return JSON.stringify(resArr); 48 | }; 49 | helper(root); 50 | return res; 51 | }; -------------------------------------------------------------------------------- /Algorithms/653两数之和 IV - 输入 BSTtwo-sum-iv-input-is-a-bst/two-sum-iv-input-is-a-bst.js: -------------------------------------------------------------------------------- 1 | /* leetcode 653两数之和 IV - 输入 BSTtwo-sum-iv-input-is-a-bst JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @param {number} k * @return {boolean} */ 4 | var findTarget = function(root, k, checkArr) { 5 | if (!root) { 6 | return false; 7 | } 8 | if (!checkArr) { 9 | checkArr = []; 10 | } 11 | var val = root.val; 12 | if (checkArr.indexOf(val) > -1) { 13 | return true; 14 | } else { /* 遍历一个节点,就把它互补的值放到一个数组。后面检测新的节点的值是不是在这个数组中。*/ 15 | checkArr.push(k - val); 16 | } 17 | return (root.left && findTarget(root.left, k, checkArr)) || (root.right && findTarget(root.right, k, checkArr)) || false; 18 | }; -------------------------------------------------------------------------------- /Algorithms/654最大二叉树maximum-binary-tree/maximum-binary-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 654最大二叉树maximum-binary-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {number[]} nums * @return {TreeNode} */ 4 | var constructMaximumBinaryTree = function(nums) { 5 | var len = nums.length; 6 | if (0 == len) { 7 | return null; 8 | } 9 | var maxI = 0; 10 | var max = nums[0]; /* 先找到最大值*/ 11 | for (var i = 1; i < len; i++) { 12 | var item = nums[i]; 13 | if (item > max) { 14 | maxI = i; 15 | max = item; 16 | } 17 | } 18 | var root = new TreeNode(max); 19 | root.left = constructMaximumBinaryTree(nums.slice(0, maxI)); 20 | root.right = constructMaximumBinaryTree(nums.slice(maxI + 1)); 21 | return root; 22 | }; -------------------------------------------------------------------------------- /Algorithms/657判断路线成圈judge-route-circle/judge-route-circle.js: -------------------------------------------------------------------------------- 1 | /* leetcode 657判断路线成圈judge-route-circle JavaScript实现 */ 2 | 3 | /** * @param {string} moves * @return {boolean} */ /*只需要判断L的数量等于R的数量。U的数量等于D的数量?*/ 4 | var judgeCircle = function(moves) { 5 | var Ls = moves.match(/L/g); 6 | var Rs = moves.match(/R/g); 7 | var Us = moves.match(/U/g); 8 | var Ds = moves.match(/D/g); 9 | var LLen = Ls ? Ls.length : 0; 10 | var RLen = Rs ? Rs.length : 0; 11 | var ULen = Us ? Us.length : 0; 12 | var DLen = Ds ? Ds.length : 0; 13 | return LLen == RLen && ULen == DLen; 14 | }; -------------------------------------------------------------------------------- /Algorithms/662二叉树最大宽度maximum-width-of-binary-tree/maximum-width-of-binary-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 662二叉树最大宽度maximum-width-of-binary-tree JavaScript实现 */ 2 | 3 | /*层次遍历,每个节点加一个index。根据上层index和left,right来计算下层的index。*/ 4 | var widthOfBinaryTree = function(root) { 5 | if (root == null) { 6 | return 0; 7 | } 8 | var checkArr = [root]; 9 | root.index = 1; 10 | var maxLen = 1; 11 | while (checkArr.length > 0) { 12 | var newCheckArr = []; 13 | for (var i = 0; i < checkArr.length; i++) { 14 | var item = checkArr[i]; 15 | if (item.left) { 16 | newCheckArr.push(item.left); 17 | item.left.index = item.index * 2 - 1; 18 | } 19 | if (item.right) { 20 | newCheckArr.push(item.right); 21 | item.right.index = item.index * 2; 22 | } 23 | } 24 | var len = checkArr[checkArr.length - 1].index - checkArr[0].index + 1; 25 | if (len > maxLen) { 26 | maxLen = len; 27 | } 28 | checkArr = newCheckArr; 29 | } 30 | return maxLen; 31 | }; -------------------------------------------------------------------------------- /Algorithms/669修剪二叉搜索树trim-a-binary-search-tree/trim-a-binary-search-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 669修剪二叉搜索树trim-a-binary-search-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @param {number} L * @param {number} R * @return {TreeNode} */ 4 | var trimBST = function(root, L, R) { 5 | if (!root) { 6 | return null; 7 | } 8 | var val = root.val; 9 | if (val < L) { 10 | return root.right ? trimBST(root.right, L, R) : null; 11 | } else if (val > R) { 12 | return root.left ? trimBST(root.left, L, R) : null; 13 | } else { 14 | if (val == L) { 15 | root.left = null; 16 | root.right = trimBST(root.right, L, R); 17 | } else if (val == R) { 18 | root.left = trimBST(root.left, L, R); 19 | root.right = null; 20 | } else { 21 | root.left = trimBST(root.left, L, R); 22 | root.right = trimBST(root.right, L, R); 23 | } 24 | return root; 25 | } 26 | }; -------------------------------------------------------------------------------- /Algorithms/671二叉树中第二小的节点second-minimum-node-in-a-binary-tree/second-minimum-node-in-a-binary-tree.js: -------------------------------------------------------------------------------- 1 | /* leetcode 671二叉树中第二小的节点second-minimum-node-in-a-binary-tree JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number} */ 4 | var findSecondMinimumValue = function(root, arr) { 5 | if (!root) { 6 | return -1; 7 | } /* arr用于保存第一小,第二小的值。*/ 8 | if (!arr) { 9 | arr = []; 10 | } 11 | var left = root.left; 12 | var right = root.right; 13 | var val = root.val; /* 把值放进去,排序。保持数组长度为2.*/ 14 | if (arr.indexOf(val) < 0) { 15 | arr.push(val); 16 | arr.sort(function(a, b) { 17 | return a - b; 18 | }); 19 | arr.splice(2); 20 | } /* 这样的可以不遍历它后面的。*/ 21 | if (left && right && arr.length == 2 && val > arr[1]) {} else { 22 | left && findSecondMinimumValue(left, arr); 23 | right && findSecondMinimumValue(right, arr); 24 | } 25 | if (arr.length < 2) { 26 | return -1; 27 | } 28 | return arr[1]; 29 | }; -------------------------------------------------------------------------------- /Algorithms/687最长同值路径longest-univalue-path/longest-univalue-path.js: -------------------------------------------------------------------------------- 1 | /* leetcode 687最长同值路径longest-univalue-path JavaScript实现 */ 2 | 3 | var longestUnivaluePath = function(root) { /* 找一个节点的同值路长度。*/ /* 传递了isRoot,表示是这次查找的根。返回左右之和。*/ /* 否则返回最大的那个。*/ 4 | var findPath = function(root, path, isRoot) { 5 | if (!root) { 6 | return 0; 7 | } 8 | if (!path) { 9 | path = 0; 10 | } 11 | var val = root.val; 12 | var leftPath = 0; 13 | if (root.left && root.left.val == root.val) { 14 | leftPath = findPath(root.left, path + 1); 15 | } 16 | var rightPath = 0; 17 | if (root.right && root.right.val == root.val) { 18 | rightPath = findPath(root.right, path + 1); 19 | } 20 | if (!isRoot) { /* 如果left,right都为0,则返回path。*/ 21 | return Math.max(leftPath, rightPath) || path; 22 | } else { 23 | return leftPath + rightPath; 24 | } 25 | } 26 | var max = 0; /* 遍历求最大*/ 27 | var readRoot = function(root) { 28 | if (!root) { 29 | return; 30 | } 31 | var rootPath = findPath(root, 0, true); 32 | if (rootPath > max) { 33 | max = rootPath; 34 | } 35 | root.left && readRoot(root.left); 36 | root.right && readRoot(root.right); 37 | } 38 | readRoot(root); 39 | return max; 40 | }; -------------------------------------------------------------------------------- /Algorithms/709转换成小写字母to-lower-case/to-lower-case.js: -------------------------------------------------------------------------------- 1 | /* leetcode 709.转换成小写字母 JavaScript实现 */ 2 | 3 | /** * @param {string} str * @return {string} */ 4 | var toLowerCase = function(str) { 5 | var bigArr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); 6 | var smallArr = 'abcdefghijklmnopqrstuvwxyz'.split(''); 7 | var replaceObj = {}; /* 生成大小字母的映射。*/ 8 | bigArr.forEach(function(v, i) { 9 | replaceObj[v] = smallArr[i]; 10 | }); 11 | var resArr = []; 12 | for (var s of str) { 13 | replaceObj[s] ? resArr.push(replaceObj[s]) : resArr.push(s); 14 | } 15 | return resArr.join(''); 16 | }; -------------------------------------------------------------------------------- /Algorithms/720词典中最长的单词longest-word-in-dictionary/longest-word-in-dictionary.js: -------------------------------------------------------------------------------- 1 | /* leetcode 720词典中最长的单词longest-word-in-dictionary JavaScript实现 */ 2 | 3 | /** * @param {string[]} words * @return {string} */ 4 | var longestWord = function(words) { 5 | var res = ''; 6 | words.forEach(function(v, i, arr) { 7 | var originV = v; 8 | while (v.length > 1) { 9 | v = v.slice(0, v.length - 1); /* 检查少一个字符的有没有在该数组中*/ 10 | if (arr.indexOf(v) < 0) { 11 | return false; 12 | } 13 | } 14 | if (originV.length > res.length) { 15 | res = originV; 16 | } /* 判断字典序*/ 17 | if (originV.length == res.length && originV < res) { 18 | res = originV; 19 | } 20 | }); 21 | return res; 22 | }; -------------------------------------------------------------------------------- /Algorithms/728自除数self-dividing-numbers/self-dividing-numbers.js: -------------------------------------------------------------------------------- 1 | /* leetcode 728自除数self-dividing-numbers JavaScript实现 */ 2 | 3 | /** * @param {number} left * @param {number} right * @return {number[]} */ 4 | var selfDividingNumbers = function(left, right) { 5 | var item = left; 6 | var res = []; 7 | while (item <= right) { 8 | if (isDividingNumbers(item)) { 9 | res.push(item); 10 | } 11 | item++; 12 | } 13 | return res; 14 | 15 | function isDividingNumbers(num) { 16 | var itemString = num.toString(); 17 | if (itemString.match(0)) { 18 | return false; 19 | } 20 | var itemArr = itemString.split(''); 21 | var itemLen = itemArr.length; 22 | for (var j = 0; j < itemLen; j++) { 23 | if (num % itemArr[j] != 0) { 24 | return false; 25 | } 26 | } 27 | return true; 28 | } 29 | }; -------------------------------------------------------------------------------- /Algorithms/744寻找比目标字母大的最小字母find-smallest-letter-greater-than-target/find-smallest-letter-greater-than-target.js: -------------------------------------------------------------------------------- 1 | /* leetcode 744寻找比目标字母大的最小字母find-smallest-letter-greater-than-target JavaScript实现 */ 2 | 3 | /** * @param {character[]} letters * @param {character} target * @return {character} */ 4 | var nextGreatestLetter = function(letters, target) { 5 | var arr = 'abcdefghijklmnopqrstuvwxyz'.split(''); 6 | var arrLen = arr.length; 7 | var i = arr.indexOf(target); 8 | while (true) { 9 | i++; 10 | if (i == arrLen) { 11 | i = 0; 12 | } 13 | if (letters.indexOf(arr[i]) > -1) { 14 | return arr[i]; 15 | } 16 | } 17 | return target; 18 | }; -------------------------------------------------------------------------------- /Algorithms/746使用最小花费爬楼梯min-cost-climbing-stairs/min-cost-climbing-stairs.js: -------------------------------------------------------------------------------- 1 | /* leetcode 746使用最小花费爬楼梯min-cost-climbing-stairs JavaScript实现 */ 2 | 3 | /*1.动态规划不一定要递归。关键是理解整个生成的流程。初始条件,以及中间值的选择逻辑。*/ 4 | var minCostClimbingStairs = function(cost) { 5 | var n = cost.length; 6 | if (cost.length < 2) { 7 | return cost[n - 1] ? cost[n - 1] : 0; 8 | } 9 | var dp = [cost[0], cost[1]]; 10 | for (var i = 2; i < n; i++) { 11 | dp.push(Math.min(dp[i - 1], dp[i - 2]) + cost[i]); 12 | } /* 这个意思是最后一步可能不踩在台阶上?而是说比如到倒数第二级,走两步,不踩在最后一级上,就不会加值?*/ 13 | return Math.min(dp[dp.length - 1], dp[dp.length - 2]); 14 | }; -------------------------------------------------------------------------------- /Algorithms/771宝石与石头jewels-and-stones/jewels-and-stones.js: -------------------------------------------------------------------------------- 1 | /* leetcode 771宝石与石头jewels-and-stones JavaScript实现 */ 2 | 3 | /** * @param {string} J * @param {string} S * @return {number} */ 4 | var numJewelsInStones = function(J, S) { 5 | var jArr = J.split(''); 6 | var jLen = jArr.length; 7 | var item, i = 0, 8 | match, reg, res = 0; 9 | for (i; i < jLen; i++) { 10 | item = jArr[i]; /* 注意这里使用变量动态生成正则。*/ 11 | reg = new RegExp(item, 'g'); 12 | var match = S.match(reg); 13 | if (match) { 14 | res = res + match.length; 15 | } 16 | } 17 | return res; 18 | }; -------------------------------------------------------------------------------- /Algorithms/784字母大小写全排列letter-case-permutation/letter-case-permutation.js: -------------------------------------------------------------------------------- 1 | /* leetcode 784字母大小写全排列letter-case-permutation JavaScript实现 */ 2 | 3 | /** * @param {string} S * @return {string[]} */ 4 | var letterCasePermutation = function(S) { 5 | if (S.length == 0) { 6 | return [""]; 7 | } 8 | var SArr = S.split(''); 9 | var reg = /[a-zA-Z]/; 10 | var partArr = []; 11 | if (SArr[0].match(reg)) { 12 | partArr = [SArr[0].toLocaleLowerCase(), SArr[0].toLocaleUpperCase()]; 13 | } else { 14 | partArr = [SArr[0]]; 15 | } 16 | var len = SArr.length; /* 如果是数字,直接加在后面。如果是字母。则原来的每一个都加一个小写,并把原来的每一个加一个大写放在数组中。*/ 17 | for (var i = 1; i < len; i++) { 18 | var item = SArr[i]; 19 | var partLen = partArr.length; 20 | var isMatch = item.match(reg); 21 | for (var j = 0; j < partLen; j++) { 22 | var partItem = partArr[j]; 23 | if (isMatch) { 24 | partArr[j] = partItem + item.toLocaleLowerCase(); 25 | partArr.push(partItem + item.toLocaleUpperCase()); 26 | } else { 27 | partArr[j] = partArr[j] + item; 28 | } 29 | } 30 | } 31 | return partArr; 32 | }; -------------------------------------------------------------------------------- /Algorithms/788旋转数字rotated-digits/rotated-digits.js: -------------------------------------------------------------------------------- 1 | /* leetcode 788旋转数字rotated-digits JavaScript实现 */ 2 | 3 | /** * @param {number} N * @return {number} */ 4 | var rotatedDigits = function(N) { 5 | var res = []; 6 | var noOkReg = /[347]+/ 7 | for (var i = 1; i <= N; i++) { 8 | var iStr = i.toString(); /* 如果含有3,4,7,跳过。*/ 9 | if (iStr.match(noOkReg)) { 10 | continue; 11 | } /* 字符串替换。*/ 12 | iStr = iStr.replace(/(2)|(5)|(6)|(9)/g, function(match, $1, $2, $3, $4) { 13 | if ($1) { 14 | return 5; 15 | } 16 | if ($2) { 17 | return 2; 18 | } 19 | if ($3) { 20 | return 9; 21 | } 22 | if ($4) { 23 | return 6; 24 | } 25 | }); 26 | if (i != parseInt(iStr)) { 27 | res.push(i); 28 | } 29 | } 30 | return res.length; 31 | }; -------------------------------------------------------------------------------- /Algorithms/791自定义字符串排序custom-sort-string/custom-sort-string.js: -------------------------------------------------------------------------------- 1 | /* leetcode 791自定义字符串排序custom-sort-string JavaScript实现 */ 2 | 3 | /** * @param {string} S * @param {string} T * @return {string} */ 4 | var customSortString = function(S, T) { 5 | var sArr = S.split(''); 6 | var sObj = {}; 7 | sArr.forEach(function(v, i) { 8 | sObj[v] = i; 9 | }); 10 | var tArr = T.split(''); 11 | var resArr = tArr.sort(function(a, b) { 12 | var indexA = sObj[a] || 0; 13 | var indexB = sObj[b] || 0; 14 | return indexA - indexB; 15 | }); 16 | return resArr.join(''); 17 | }; -------------------------------------------------------------------------------- /Algorithms/796旋转字符串rotate-string/rotate-string.js: -------------------------------------------------------------------------------- 1 | /* leetcode 796旋转字符串rotate-string JavaScript实现 */ 2 | 3 | /** * @param {string} A * @param {string} B * @return {boolean} */ 4 | var rotateString = function(A, B) { 5 | if (A.length != B.length) { 6 | return false; 7 | } /* 拼起来,看在里面不。*/ 8 | if ((B + B).indexOf(A) > -1) { 9 | return true; 10 | } 11 | return false; 12 | }; -------------------------------------------------------------------------------- /Algorithms/806写字符串需要的行数number-of-lines-to-write-string/number-of-lines-to-write-string.js: -------------------------------------------------------------------------------- 1 | /* leetcode 806写字符串需要的行数number-of-lines-to-write-string JavaScript实现 */ 2 | 3 | /** * @param {number[]} widths * @param {string} S * @return {number[]} */ 4 | var numberOfLines = function(widths, S) { 5 | var arr = 'abcdefghijklmnopqrstuvwxyz'.split(''); 6 | var map = {}; /* 每个字母的序号映射*/ 7 | arr.forEach(function(v, i) { 8 | map[v] = widths[i]; 9 | }); 10 | var sArr = S.split(''); 11 | var row = 1; 12 | var countNum = 0; 13 | sArr.forEach(function(v, i) { 14 | var wLen = map[v]; /* 如果加上最后一个字超过了100,则加一行,新一行有n位。*/ 15 | if (countNum + wLen > 100) { 16 | row++; 17 | countNum = wLen; 18 | } else { 19 | countNum = countNum + wLen; 20 | } 21 | }); 22 | return [row, countNum]; 23 | }; -------------------------------------------------------------------------------- /Algorithms/811子域名访问计数subdomain-visit-count/subdomain-visit-count.js: -------------------------------------------------------------------------------- 1 | /* leetcode 811子域名访问计数subdomain-visit-count JavaScript实现 */ 2 | 3 | /** * @param {string[]} cpdomains * @return {string[]} */ 4 | var subdomainVisits = function(cpdomains) { 5 | var obj = {}; 6 | cpdomains.forEach(function(cpdomain, i) { 7 | var splitArr = cpdomain.split(' '); 8 | var domainArr = splitArr[1].split('.'); 9 | var count = parseInt(splitArr[0], 10); 10 | var okDomain = ''; 11 | var len = domainArr.length; /* 翻转了一下。*/ 12 | domainArr.reverse().forEach(function(domain, j) { 13 | if (!okDomain) { 14 | okDomain = domain; 15 | } else { 16 | okDomain = domain + '.' + okDomain; 17 | } 18 | if (!obj[okDomain]) { 19 | obj[okDomain] = 0; 20 | } 21 | obj[okDomain] += count; 22 | }) 23 | }); 24 | var res = []; 25 | for (var k in obj) { 26 | if (obj.hasOwnProperty(k)) { 27 | res.push(obj[k] + ' ' + k); 28 | } 29 | } 30 | return res; 31 | }; -------------------------------------------------------------------------------- /Algorithms/814二叉树剪枝binary-tree-pruning/binary-tree-pruning.js: -------------------------------------------------------------------------------- 1 | /* leetcode 814二叉树剪枝binary-tree-pruning JavaScript实现 */ 2 | 3 | /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {TreeNode} */ 4 | var pruneTree = function(root) { /* 子节点(包括自己)是否不包含0的。*/ 5 | function findOne(root) { 6 | if (!root) { 7 | return false; 8 | } 9 | if (root.val == 1) { 10 | return true; 11 | } 12 | if (!root.left && !root.right) { 13 | return root.val == 1; 14 | } 15 | return (root.left && findOne(root.left)) || (root.right && findOne(root.right)) || false; 16 | } 17 | if (!findOne(root)) { 18 | root = null; 19 | return root; 20 | } 21 | if (!findOne(root.left)) { 22 | root.left = null; 23 | } else { 24 | pruneTree(root.left); 25 | } 26 | if (!findOne(root.right)) { 27 | root.right = null; 28 | } else { 29 | pruneTree(root.right); 30 | } 31 | return root; 32 | }; -------------------------------------------------------------------------------- /Algorithms/819最常见的单词most-common-word/most-common-word.js: -------------------------------------------------------------------------------- 1 | /* leetcode 819最常见的单词most-common-word JavaScript实现 */ 2 | 3 | /** * @param {string} paragraph * @param {string[]} banned * @return {string} */ 4 | var mostCommonWord = function(paragraph, banned) { /* 转成小写先。*/ 5 | var s = paragraph.toLocaleLowerCase(); /* 替换标点符号*/ 6 | s = s.replace(/!|\?|'|,|;|\./g, ''); 7 | var sArr = s.split(/\s+/); 8 | var map = {}; 9 | var res = ''; /* 统计*/ 10 | for (var i = 0; i < sArr.length; i++) { 11 | var item = sArr[i]; /* 跳过。*/ 12 | if (banned.indexOf(item) > -1) { 13 | continue; 14 | } 15 | if (!map[item]) { 16 | map[item] = 0; 17 | } 18 | map[item]++; 19 | if (res) { 20 | if (map[item] > map[res]) { 21 | res = item; 22 | } 23 | } else { 24 | res = item; 25 | } 26 | } 27 | return res; 28 | }; -------------------------------------------------------------------------------- /Algorithms/832翻转图像flipping-an-image/flipping-an-image.js: -------------------------------------------------------------------------------- 1 | /* leetcode 832.翻转图像 JavaScript实现 */ 2 | 3 | /** * @param {number[][]} A * @return {number[][]} */ 4 | var flipAndInvertImage = function(A) { 5 | var resArr = A.map(function(arr) { 6 | var reversedArr = arr.reverse(); 7 | reversedArr.forEach(function(v, i) { 8 | reversedArr[i] = (v == 0) ? 1 : 0; 9 | }); 10 | return reversedArr; 11 | }); 12 | return resArr; 13 | }; -------------------------------------------------------------------------------- /Algorithms/844比较含退格的字符串backspace-string-compare/backspace-string-compare.js: -------------------------------------------------------------------------------- 1 | /* leetcode 844.比较含退格的字符串 JavaScript实现 */ 2 | 3 | var backspaceCompare = function(S, T) { 4 | function deal(str) { 5 | var arr = str.split(''); 6 | for (var i = 0; i < arr.length;) { 7 | var item = arr[i]; 8 | if (item == '#') { /* 如果它前面有值,删除自身和前一位*/ 9 | if (i - 1 > -1) { 10 | arr.splice(i - 1, 2); 11 | i = i - 1; 12 | } else { /* 删除自身*/ 13 | arr.splice(i, 1); 14 | } 15 | } else { /* 处理下一位*/ 16 | i++; 17 | } 18 | } 19 | return arr.join(''); 20 | } 21 | return deal(S) == deal(T); 22 | }; -------------------------------------------------------------------------------- /batch_files.js: -------------------------------------------------------------------------------- 1 | // 批处理文件。 2 | 3 | var fs = require("fs") 4 | var path = require("path") 5 | 6 | var root = path.join(__dirname, 'Algorithms/') 7 | 8 | readDir(path.join(root)) 9 | 10 | function readDir(path) { 11 | fs.readdir(path, function(err, menu) { 12 | if (!menu) 13 | return; 14 | 15 | menu.forEach(function(ele) { 16 | 17 | var folder = fs.statSync(path + "/" + ele); 18 | if (folder.isDirectory()) { 19 | 20 | fs.readdir(path + "/" + ele, function(err, fileArr) { 21 | createFile(path + "/" + ele + "/" + fileArr[0], ele); 22 | }) 23 | } 24 | 25 | }) 26 | }) 27 | } 28 | 29 | 30 | //给所有之前的文件加上题目。增加曝光度。 31 | function createFile(path, folderName) { 32 | 33 | if (!fs.existsSync(path)) { 34 | return; 35 | } 36 | //加上这一句,增加被搜索到的概率。 37 | var prefix = '/* leetcode ' + folderName + ' JavaScript实现 ' + '*/\n\n' 38 | var fileStr = fs.readFileSync(path, 'utf8'); 39 | //如果已经处理过了就退出。 40 | if (fileStr.indexOf(prefix) > -1) { 41 | return; 42 | } 43 | 44 | fs.writeFile(path, prefix + fileStr, function() {}); 45 | 46 | }; -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leetcode", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/node": { 8 | "version": "9.6.5", 9 | "resolved": "http://registry.npm.taobao.org/@types/node/download/@types/node-9.6.5.tgz", 10 | "integrity": "sha1-7nAIEP30msHDmfxZgLdVmz5aOB0=" 11 | }, 12 | "abbrev": { 13 | "version": "1.1.1", 14 | "resolved": "http://registry.npm.taobao.org/abbrev/download/abbrev-1.1.1.tgz", 15 | "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg=", 16 | "dev": true 17 | }, 18 | "agent-base": { 19 | "version": "4.2.0", 20 | "resolved": "http://registry.npm.taobao.org/agent-base/download/agent-base-4.2.0.tgz", 21 | "integrity": "sha1-mDi1wzkrliutAx5qTF4QJKvsRc4=", 22 | "requires": { 23 | "es6-promisify": "5.0.0" 24 | } 25 | }, 26 | "async-limiter": { 27 | "version": "1.0.0", 28 | "resolved": "http://registry.npm.taobao.org/async-limiter/download/async-limiter-1.0.0.tgz", 29 | "integrity": "sha1-ePrtjD0HSrgfIrTphdeehzj3IPg=" 30 | }, 31 | "asynckit": { 32 | "version": "0.4.0", 33 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 34 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 35 | }, 36 | "balanced-match": { 37 | "version": "1.0.0", 38 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 39 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 40 | }, 41 | "bluebird": { 42 | "version": "3.5.1", 43 | "resolved": "http://registry.npm.taobao.org/bluebird/download/bluebird-3.5.1.tgz", 44 | "integrity": "sha1-2VUfnemPH82h5oPRfukaBgLuLrk=", 45 | "dev": true 46 | }, 47 | "boolbase": { 48 | "version": "1.0.0", 49 | "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", 50 | "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" 51 | }, 52 | "brace-expansion": { 53 | "version": "1.1.11", 54 | "resolved": "http://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz", 55 | "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", 56 | "requires": { 57 | "balanced-match": "1.0.0", 58 | "concat-map": "0.0.1" 59 | } 60 | }, 61 | "cheerio": { 62 | "version": "1.0.0-rc.2", 63 | "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.2.tgz", 64 | "integrity": "sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs=", 65 | "requires": { 66 | "css-select": "1.2.0", 67 | "dom-serializer": "0.1.0", 68 | "entities": "1.1.1", 69 | "htmlparser2": "3.9.2", 70 | "lodash": "4.17.5", 71 | "parse5": "3.0.3" 72 | } 73 | }, 74 | "combined-stream": { 75 | "version": "1.0.6", 76 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", 77 | "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", 78 | "requires": { 79 | "delayed-stream": "1.0.0" 80 | } 81 | }, 82 | "commander": { 83 | "version": "2.15.1", 84 | "resolved": "http://registry.npm.taobao.org/commander/download/commander-2.15.1.tgz", 85 | "integrity": "sha1-30boZ9D8Kuxmo0ZitAapzK//Ww8=", 86 | "dev": true 87 | }, 88 | "component-emitter": { 89 | "version": "1.2.1", 90 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", 91 | "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" 92 | }, 93 | "concat-map": { 94 | "version": "0.0.1", 95 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 96 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 97 | }, 98 | "concat-stream": { 99 | "version": "1.6.0", 100 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", 101 | "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", 102 | "requires": { 103 | "inherits": "2.0.3", 104 | "readable-stream": "2.3.6", 105 | "typedarray": "0.0.6" 106 | } 107 | }, 108 | "config-chain": { 109 | "version": "1.1.11", 110 | "resolved": "http://registry.npm.taobao.org/config-chain/download/config-chain-1.1.11.tgz", 111 | "integrity": "sha1-q6CXR9++TD5w52am5BWG4YWfxvI=", 112 | "dev": true, 113 | "requires": { 114 | "ini": "1.3.5", 115 | "proto-list": "1.2.4" 116 | } 117 | }, 118 | "cookiejar": { 119 | "version": "2.1.1", 120 | "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.1.tgz", 121 | "integrity": "sha1-Qa1XsbVVlR7BcUEqgZQrHoIA00o=" 122 | }, 123 | "core-util-is": { 124 | "version": "1.0.2", 125 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 126 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 127 | }, 128 | "css-select": { 129 | "version": "1.2.0", 130 | "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", 131 | "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", 132 | "requires": { 133 | "boolbase": "1.0.0", 134 | "css-what": "2.1.0", 135 | "domutils": "1.5.1", 136 | "nth-check": "1.0.1" 137 | } 138 | }, 139 | "css-what": { 140 | "version": "2.1.0", 141 | "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", 142 | "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=" 143 | }, 144 | "debug": { 145 | "version": "3.1.0", 146 | "resolved": "http://registry.npm.taobao.org/debug/download/debug-3.1.0.tgz", 147 | "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", 148 | "requires": { 149 | "ms": "2.0.0" 150 | } 151 | }, 152 | "delayed-stream": { 153 | "version": "1.0.0", 154 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 155 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 156 | }, 157 | "dom-serializer": { 158 | "version": "0.1.0", 159 | "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", 160 | "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", 161 | "requires": { 162 | "domelementtype": "1.1.3", 163 | "entities": "1.1.1" 164 | }, 165 | "dependencies": { 166 | "domelementtype": { 167 | "version": "1.1.3", 168 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", 169 | "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=" 170 | } 171 | } 172 | }, 173 | "domelementtype": { 174 | "version": "1.3.0", 175 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", 176 | "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=" 177 | }, 178 | "domhandler": { 179 | "version": "2.4.1", 180 | "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", 181 | "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=", 182 | "requires": { 183 | "domelementtype": "1.3.0" 184 | } 185 | }, 186 | "domutils": { 187 | "version": "1.5.1", 188 | "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", 189 | "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", 190 | "requires": { 191 | "dom-serializer": "0.1.0", 192 | "domelementtype": "1.3.0" 193 | } 194 | }, 195 | "editorconfig": { 196 | "version": "0.13.3", 197 | "resolved": "http://registry.npm.taobao.org/editorconfig/download/editorconfig-0.13.3.tgz", 198 | "integrity": "sha1-5SGeWHlR1glY/ZTqmpoAjN7/GzQ=", 199 | "dev": true, 200 | "requires": { 201 | "bluebird": "3.5.1", 202 | "commander": "2.15.1", 203 | "lru-cache": "3.2.0", 204 | "semver": "5.5.0", 205 | "sigmund": "1.0.1" 206 | } 207 | }, 208 | "entities": { 209 | "version": "1.1.1", 210 | "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", 211 | "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" 212 | }, 213 | "es6-promise": { 214 | "version": "4.2.4", 215 | "resolved": "http://registry.npm.taobao.org/es6-promise/download/es6-promise-4.2.4.tgz", 216 | "integrity": "sha1-3EIhwrFlGHYL2MOaUtjzVvwA7Sk=" 217 | }, 218 | "es6-promisify": { 219 | "version": "5.0.0", 220 | "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", 221 | "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", 222 | "requires": { 223 | "es6-promise": "4.2.4" 224 | } 225 | }, 226 | "extend": { 227 | "version": "3.0.1", 228 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", 229 | "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" 230 | }, 231 | "extract-zip": { 232 | "version": "1.6.6", 233 | "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", 234 | "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", 235 | "requires": { 236 | "concat-stream": "1.6.0", 237 | "debug": "2.6.9", 238 | "mkdirp": "0.5.0", 239 | "yauzl": "2.4.1" 240 | }, 241 | "dependencies": { 242 | "debug": { 243 | "version": "2.6.9", 244 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 245 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 246 | "requires": { 247 | "ms": "2.0.0" 248 | } 249 | } 250 | } 251 | }, 252 | "fd-slicer": { 253 | "version": "1.0.1", 254 | "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", 255 | "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", 256 | "requires": { 257 | "pend": "1.2.0" 258 | } 259 | }, 260 | "form-data": { 261 | "version": "2.3.2", 262 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", 263 | "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", 264 | "requires": { 265 | "asynckit": "0.4.0", 266 | "combined-stream": "1.0.6", 267 | "mime-types": "2.1.18" 268 | } 269 | }, 270 | "formidable": { 271 | "version": "1.2.1", 272 | "resolved": "http://registry.npm.taobao.org/formidable/download/formidable-1.2.1.tgz", 273 | "integrity": "sha1-cPt8oCkO5v+WEJBBX0s989IIJlk=" 274 | }, 275 | "fs.realpath": { 276 | "version": "1.0.0", 277 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 278 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 279 | }, 280 | "glob": { 281 | "version": "7.1.2", 282 | "resolved": "http://registry.npm.taobao.org/glob/download/glob-7.1.2.tgz", 283 | "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", 284 | "requires": { 285 | "fs.realpath": "1.0.0", 286 | "inflight": "1.0.6", 287 | "inherits": "2.0.3", 288 | "minimatch": "3.0.4", 289 | "once": "1.4.0", 290 | "path-is-absolute": "1.0.1" 291 | } 292 | }, 293 | "htmlparser2": { 294 | "version": "3.9.2", 295 | "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", 296 | "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", 297 | "requires": { 298 | "domelementtype": "1.3.0", 299 | "domhandler": "2.4.1", 300 | "domutils": "1.5.1", 301 | "entities": "1.1.1", 302 | "inherits": "2.0.3", 303 | "readable-stream": "2.3.6" 304 | } 305 | }, 306 | "https-proxy-agent": { 307 | "version": "2.2.1", 308 | "resolved": "http://registry.npm.taobao.org/https-proxy-agent/download/https-proxy-agent-2.2.1.tgz", 309 | "integrity": "sha1-UVUpcPoE1yPgTFbQQXjD+SWSu8A=", 310 | "requires": { 311 | "agent-base": "4.2.0", 312 | "debug": "3.1.0" 313 | } 314 | }, 315 | "inflight": { 316 | "version": "1.0.6", 317 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 318 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 319 | "requires": { 320 | "once": "1.4.0", 321 | "wrappy": "1.0.2" 322 | } 323 | }, 324 | "inherits": { 325 | "version": "2.0.3", 326 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 327 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 328 | }, 329 | "ini": { 330 | "version": "1.3.5", 331 | "resolved": "http://registry.npm.taobao.org/ini/download/ini-1.3.5.tgz", 332 | "integrity": "sha1-7uJfVtscnsYIXgwid4CD9Zar+Sc=", 333 | "dev": true 334 | }, 335 | "isarray": { 336 | "version": "1.0.0", 337 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 338 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 339 | }, 340 | "js-beautify": { 341 | "version": "1.7.5", 342 | "resolved": "http://registry.npm.taobao.org/js-beautify/download/js-beautify-1.7.5.tgz", 343 | "integrity": "sha1-adllHvYNu2SfZVJ7U2dJUBOKeRk=", 344 | "dev": true, 345 | "requires": { 346 | "config-chain": "1.1.11", 347 | "editorconfig": "0.13.3", 348 | "mkdirp": "0.5.0", 349 | "nopt": "3.0.6" 350 | } 351 | }, 352 | "lodash": { 353 | "version": "4.17.5", 354 | "resolved": "http://registry.npm.taobao.org/lodash/download/lodash-4.17.5.tgz", 355 | "integrity": "sha1-maktZcAnLevoyWtgV7yPv6O+1RE=" 356 | }, 357 | "lru-cache": { 358 | "version": "3.2.0", 359 | "resolved": "http://registry.npm.taobao.org/lru-cache/download/lru-cache-3.2.0.tgz", 360 | "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=", 361 | "dev": true, 362 | "requires": { 363 | "pseudomap": "1.0.2" 364 | } 365 | }, 366 | "methods": { 367 | "version": "1.1.2", 368 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 369 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 370 | }, 371 | "mime": { 372 | "version": "1.6.0", 373 | "resolved": "http://registry.npm.taobao.org/mime/download/mime-1.6.0.tgz", 374 | "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=" 375 | }, 376 | "mime-db": { 377 | "version": "1.33.0", 378 | "resolved": "http://registry.npm.taobao.org/mime-db/download/mime-db-1.33.0.tgz", 379 | "integrity": "sha1-o0kgUKXLm2NFBUHjnZeI0icng9s=" 380 | }, 381 | "mime-types": { 382 | "version": "2.1.18", 383 | "resolved": "http://registry.npm.taobao.org/mime-types/download/mime-types-2.1.18.tgz", 384 | "integrity": "sha1-bzI/YKg9ERRvgx/xH9ZuL+VQO7g=", 385 | "requires": { 386 | "mime-db": "1.33.0" 387 | } 388 | }, 389 | "minimatch": { 390 | "version": "3.0.4", 391 | "resolved": "http://registry.npm.taobao.org/minimatch/download/minimatch-3.0.4.tgz", 392 | "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", 393 | "requires": { 394 | "brace-expansion": "1.1.11" 395 | } 396 | }, 397 | "minimist": { 398 | "version": "0.0.8", 399 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 400 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 401 | }, 402 | "mkdirp": { 403 | "version": "0.5.0", 404 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", 405 | "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", 406 | "requires": { 407 | "minimist": "0.0.8" 408 | } 409 | }, 410 | "ms": { 411 | "version": "2.0.0", 412 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 413 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 414 | }, 415 | "nopt": { 416 | "version": "3.0.6", 417 | "resolved": "http://registry.npm.taobao.org/nopt/download/nopt-3.0.6.tgz", 418 | "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", 419 | "dev": true, 420 | "requires": { 421 | "abbrev": "1.1.1" 422 | } 423 | }, 424 | "nth-check": { 425 | "version": "1.0.1", 426 | "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", 427 | "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", 428 | "requires": { 429 | "boolbase": "1.0.0" 430 | } 431 | }, 432 | "once": { 433 | "version": "1.4.0", 434 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 435 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 436 | "requires": { 437 | "wrappy": "1.0.2" 438 | } 439 | }, 440 | "parse5": { 441 | "version": "3.0.3", 442 | "resolved": "http://registry.npm.taobao.org/parse5/download/parse5-3.0.3.tgz", 443 | "integrity": "sha1-BC95L/3TaFFVHPTp4Gazh0q0W1w=", 444 | "requires": { 445 | "@types/node": "9.6.5" 446 | } 447 | }, 448 | "path-is-absolute": { 449 | "version": "1.0.1", 450 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 451 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 452 | }, 453 | "pend": { 454 | "version": "1.2.0", 455 | "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", 456 | "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" 457 | }, 458 | "process-nextick-args": { 459 | "version": "2.0.0", 460 | "resolved": "http://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.0.tgz", 461 | "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=" 462 | }, 463 | "progress": { 464 | "version": "2.0.0", 465 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", 466 | "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=" 467 | }, 468 | "proto-list": { 469 | "version": "1.2.4", 470 | "resolved": "http://registry.npm.taobao.org/proto-list/download/proto-list-1.2.4.tgz", 471 | "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", 472 | "dev": true 473 | }, 474 | "proxy-from-env": { 475 | "version": "1.0.0", 476 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", 477 | "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=" 478 | }, 479 | "pseudomap": { 480 | "version": "1.0.2", 481 | "resolved": "http://registry.npm.taobao.org/pseudomap/download/pseudomap-1.0.2.tgz", 482 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", 483 | "dev": true 484 | }, 485 | "puppeteer": { 486 | "version": "1.3.0", 487 | "resolved": "http://registry.npm.taobao.org/puppeteer/download/puppeteer-1.3.0.tgz", 488 | "integrity": "sha1-9XHF8nFTyhZKgYjmMozi5JRoePM=", 489 | "requires": { 490 | "debug": "2.6.9", 491 | "extract-zip": "1.6.6", 492 | "https-proxy-agent": "2.2.1", 493 | "mime": "1.6.0", 494 | "progress": "2.0.0", 495 | "proxy-from-env": "1.0.0", 496 | "rimraf": "2.6.2", 497 | "ws": "3.3.3" 498 | }, 499 | "dependencies": { 500 | "debug": { 501 | "version": "2.6.9", 502 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 503 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 504 | "requires": { 505 | "ms": "2.0.0" 506 | } 507 | } 508 | } 509 | }, 510 | "qs": { 511 | "version": "6.5.1", 512 | "resolved": "http://registry.npm.taobao.org/qs/download/qs-6.5.1.tgz", 513 | "integrity": "sha1-NJzfbu+J7EXBLX1es/wMhwNDptg=" 514 | }, 515 | "readable-stream": { 516 | "version": "2.3.6", 517 | "resolved": "http://registry.npm.taobao.org/readable-stream/download/readable-stream-2.3.6.tgz", 518 | "integrity": "sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8=", 519 | "requires": { 520 | "core-util-is": "1.0.2", 521 | "inherits": "2.0.3", 522 | "isarray": "1.0.0", 523 | "process-nextick-args": "2.0.0", 524 | "safe-buffer": "5.1.1", 525 | "string_decoder": "1.1.1", 526 | "util-deprecate": "1.0.2" 527 | } 528 | }, 529 | "rimraf": { 530 | "version": "2.6.2", 531 | "resolved": "http://registry.npm.taobao.org/rimraf/download/rimraf-2.6.2.tgz", 532 | "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", 533 | "requires": { 534 | "glob": "7.1.2" 535 | } 536 | }, 537 | "safe-buffer": { 538 | "version": "5.1.1", 539 | "resolved": "http://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.1.tgz", 540 | "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=" 541 | }, 542 | "semver": { 543 | "version": "5.5.0", 544 | "resolved": "http://registry.npm.taobao.org/semver/download/semver-5.5.0.tgz", 545 | "integrity": "sha1-3Eu8emyp2Rbe5dQ1FvAJK1j3uKs=", 546 | "dev": true 547 | }, 548 | "sigmund": { 549 | "version": "1.0.1", 550 | "resolved": "http://registry.npm.taobao.org/sigmund/download/sigmund-1.0.1.tgz", 551 | "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", 552 | "dev": true 553 | }, 554 | "string_decoder": { 555 | "version": "1.1.1", 556 | "resolved": "http://registry.npm.taobao.org/string_decoder/download/string_decoder-1.1.1.tgz", 557 | "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", 558 | "requires": { 559 | "safe-buffer": "5.1.1" 560 | } 561 | }, 562 | "superagent": { 563 | "version": "3.8.2", 564 | "resolved": "http://registry.npm.taobao.org/superagent/download/superagent-3.8.2.tgz", 565 | "integrity": "sha1-5KEbnQR/fT7+s7vlNtnsACHRZAM=", 566 | "requires": { 567 | "component-emitter": "1.2.1", 568 | "cookiejar": "2.1.1", 569 | "debug": "3.1.0", 570 | "extend": "3.0.1", 571 | "form-data": "2.3.2", 572 | "formidable": "1.2.1", 573 | "methods": "1.1.2", 574 | "mime": "1.6.0", 575 | "qs": "6.5.1", 576 | "readable-stream": "2.3.6" 577 | } 578 | }, 579 | "typedarray": { 580 | "version": "0.0.6", 581 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 582 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" 583 | }, 584 | "ultron": { 585 | "version": "1.1.1", 586 | "resolved": "http://registry.npm.taobao.org/ultron/download/ultron-1.1.1.tgz", 587 | "integrity": "sha1-n+FTahCmZKZSZqHjzPhf02MCvJw=" 588 | }, 589 | "util-deprecate": { 590 | "version": "1.0.2", 591 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 592 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 593 | }, 594 | "wrappy": { 595 | "version": "1.0.2", 596 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 597 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 598 | }, 599 | "ws": { 600 | "version": "3.3.3", 601 | "resolved": "http://registry.npm.taobao.org/ws/download/ws-3.3.3.tgz", 602 | "integrity": "sha1-8c+E/i1ekB686U767OeF8YeiKPI=", 603 | "requires": { 604 | "async-limiter": "1.0.0", 605 | "safe-buffer": "5.1.1", 606 | "ultron": "1.1.1" 607 | } 608 | }, 609 | "yauzl": { 610 | "version": "2.4.1", 611 | "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", 612 | "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", 613 | "requires": { 614 | "fd-slicer": "1.0.1" 615 | } 616 | } 617 | } 618 | } 619 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leetcode", 3 | "version": "1.0.0", 4 | "description": "my answers", 5 | "main": "spider.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/liusaint/leetcode.git" 12 | }, 13 | "keywords": [ 14 | "leetcode" 15 | ], 16 | "author": "", 17 | "license": "ISC", 18 | "bugs": { 19 | "url": "https://github.com/liusaint/leetcode/issues" 20 | }, 21 | "homepage": "https://github.com/liusaint/leetcode#readme", 22 | "dependencies": { 23 | "cheerio": "^1.0.0-rc.2", 24 | "puppeteer": "^1.3.0", 25 | "superagent": "^3.8.2" 26 | }, 27 | "devDependencies": { 28 | "js-beautify": "^1.7.5" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /spider.js: -------------------------------------------------------------------------------- 1 | /*用于从https://leetcode-cn.com爬取题目和完成状态。 2 | *ls 20180421 3 | */ 4 | 5 | //node端的jQuery? 6 | const cheerio = require('cheerio'); 7 | 8 | //登录页面 9 | const loginUrl = 'https://leetcode-cn.com/accounts/login/'; 10 | // 要抓取的问题页面。 11 | const url = 'https://leetcode-cn.com/problemset/algorithms/'; 12 | //用于加载页面。 13 | const puppeteer = require('puppeteer'); 14 | 15 | const baseUrl = 'https://leetcode-cn.com'; 16 | const fs = require('fs'); 17 | const path = require('path'); 18 | //用于把拿到的js字符串格式化。 19 | const beautyJs = require('js-beautify'); 20 | //将用户名和密码保存在这个文件。这个文件不上传到github,避免泄露。 21 | const setting = require('./config.js'); 22 | //登录。密码可别泄露了。。。 23 | const user = setting.user; 24 | const pwd = setting.password; 25 | 26 | let questionArr = []; 27 | 28 | (async () => { 29 | const browser = await puppeteer.launch(); 30 | const page = await browser.newPage(); 31 | page.setViewport({ 32 | width: 1200, 33 | height: 1920 34 | }) 35 | //到登录页面 36 | await page.goto(loginUrl); 37 | 38 | await page.type('#id_login', user); 39 | await page.type('#id_password', pwd); 40 | 41 | await page.click('.auth-action-btn'); 42 | 43 | //等待页面加载出来,等同于window.onload 44 | await page.waitForNavigation({ 45 | waitUntil: 'load' 46 | }); 47 | 48 | await page.goto(url); 49 | 50 | //延迟2s等页面内容加载出来。 51 | await timeout(2000); 52 | await page.evaluate(() => { 53 | //设置每页的数量为全部。然后刷新。 54 | var pageSize = $('.reactable-pagination .form-control').find('option:last-child').val(); 55 | localStorage.setItem('problem-list:itemsPerPage', pageSize); 56 | location.reload() 57 | 58 | }); 59 | await timeout(4000); 60 | await page.screenshot({ 61 | path: 'page.png' 62 | }); //截个图 63 | 64 | // return; 65 | //获取url。 66 | const html = await page.$eval('body', e => e.outerHTML); 67 | // await browser.close(); 68 | 69 | let $ = cheerio.load(html); 70 | 71 | $(".table-striped .reactable-data tr").each(function(i, el) { 72 | var tds = $(el).find('td'); 73 | var obj = { 74 | status: tds.eq(0).attr('value') == 'ac' ? '√' : ' ', 75 | index: tds.eq(1).text(), 76 | title: tds.eq(2).text().trim(), 77 | href: baseUrl + tds.eq(2).find('a').attr('href'), 78 | rate: tds.eq(4).text(), 79 | level: tds.eq(5).text(), 80 | } 81 | // https://github.com/liusaint/ls-blog/tree/master/code/es6/es6.js 82 | // https://github.com/liusaint/leetcode 83 | // 84 | if (obj.status == '√') { 85 | //已解决的页面。 86 | obj.codeHref = obj.href + '/submissions/'; 87 | // obj.getHref = '' 88 | obj.fileName = obj.href.split('https://leetcode-cn.com/problems/')[1]; 89 | //使用中文名+链接中的英文命名 90 | obj.folderName = 'Algorithms/' + getIndex(obj.index) + obj.title  +  obj.fileName; 91 | obj.fullPath = obj.folderName + "/" + obj.fileName + ".js"; 92 | obj.gitHref = 'https://github.com/liusaint/leetcode/blob/master/' + obj.fullPath; 93 | 94 | obj.gitHref = obj.gitHref.replace(/\s/g, '%20'); 95 | } else { 96 | obj.gitHref = ''; 97 | } 98 | questionArr.push(obj); 99 | }) 100 | 101 | createMd($); 102 | 103 | createFiles(browser, page); 104 | 105 | })(); 106 | 107 | //生成表格 108 | function createTable(arr) { 109 | var header = ` 序号 | 题名 | 通过率 | 难度 | 答案 |状态 \n---|---|---|---|---|---\n` 110 | var resArr = arr.map(function(obj) { 111 | var look = obj.gitHref ? `[JavaScript](${obj.gitHref})` : ''; 112 | return ` ${obj.index} | [${obj.title}](${obj.href}) | ${obj.rate} | ${obj.level} | ${look} | ${obj.status}`; 113 | }) 114 | return header + resArr.join('\n'); 115 | } 116 | 117 | 118 | //生成readme文件 119 | function createMd($) { 120 | //生成markdown表格的字符串 121 | var table = createTable(questionArr); 122 | //进度 123 | var progress = $(".question-solved").text(); 124 | 125 | 126 | //读取readme.md。替换指定位置的内容 。填入表格。 127 | fs.readFile('./README.md', 'utf8', function(err, data) { 128 | if (err) throw err; 129 | var res = data.replace(/解题进度:[\s\S]+?\n/, '解题进度:' + progress + '\n'); 130 | var res = res.replace(/### 表格[\s\S]+\n表格结束/, '### 表格\n' + table + '\n表格结束'); 131 | fs.writeFileSync(path.join(__dirname, 'README.md'), res); 132 | }); 133 | 134 | } 135 | 136 | 137 | //根据爬到的文件调用 beautyJs格式化并生成文件。 138 | function createFile(obj) { 139 | 140 | if (!fs.existsSync(obj.folderName)) { 141 | fs.mkdirSync(obj.folderName) 142 | } 143 | //加上这一句,增加被搜索到的概率。 144 | var fileStr = '/* leetcode ' + obj.index + '.' + obj.title + ' JavaScript实现 ' + '*/\n\n'+ obj.code; 145 | fs.writeFile(obj.fullPath, beautyJs(fileStr, { 146 | indent_size: 4, 147 | space_in_empty_paren: true 148 | }), function() {}); 149 | 150 | }; 151 | 152 | 153 | //遍历文件url。依次爬取每一个解答。 154 | async function createFiles(browser, page) { 155 | 156 | // questionArr.length = 8; 157 | for (var i = 0; i < questionArr.length; i++) { 158 | 159 | var obj = questionArr[i]; 160 | if (!obj.gitHref) { 161 | continue; 162 | } 163 | //文件已经有了,跳过。 164 | if (fs.existsSync(obj.fullPath)) { 165 | continue; 166 | } 167 | //到查看提交记录页面。 168 | // console.log(obj.codeHref); 169 | await page.goto(obj.codeHref + "/1", { 170 | waitUntil: 'networkidle0' 171 | }); 172 | 173 | await timeout(2000) 174 | // await page.screenshot({ 175 | // path: obj.fileName + '.png' 176 | // }); //截个图 177 | //跳转到详情页面。 178 | await page.evaluate(() => { 179 | $('a.text-success')[0].click() 180 | }); 181 | 182 | await timeout(2000); 183 | 184 | // await page.screenshot({ 185 | // path: obj.fileName + '11.png' 186 | // }); //截个图 187 | 188 | 189 | obj.code = await page.evaluate(() => { 190 | //替换注释。不删除的话拿来的代码会有问题。 191 | if ($(".ace_cjk").parent().length > 0) { 192 | $(".ace_cjk").parent().each(function(index, el) { 193 | var text = $(el).text(); 194 | // 对于本来就是在这样注释的,不进行处理。 195 | // if(text.inexOf('/*')>-1||text.indexOf('*/')>-1){ 196 | // return; 197 | // } 198 | 199 | text = text.replace("//", ''); 200 | $(el).text('/*' + text + "*/"); 201 | }) 202 | } 203 | return $(".ace_content").text(); 204 | }); 205 | 206 | createFile(obj); 207 | 208 | } 209 | 210 | browser.close(); 211 | 212 | 213 | } 214 | 215 | //一个简单的延时。 216 | function timeout(inteval) { 217 | return new Promise(function(resolve, reject) { 218 | setTimeout(function() { 219 | resolve() 220 | }, inteval); 221 | }) 222 | } 223 | 224 | 225 | //补全三位 226 | function getIndex(num) { 227 | var len = num.toString().length; 228 | if (len == 1) { 229 | return '00' + num; 230 | } 231 | if (len == 2) { 232 | return '0' + num; 233 | } 234 | return num; 235 | } -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var beautyJs = require('js-beautify'); 2 | 3 | 4 | var ori = "/** * @param {string} word * @return {boolean} */var detectCapitalUse = function(word) {    var bigReg = /[A-Z]+/g;    var smallReg = /[a-z]+/g;    var wordLen = word.length;​​    function match(word, reg) {​        if (word == '') {            return true;       }        var len = word.length;        var match = word.match(reg);        if (match && match[0].length == len) {            return true;       }        return false;   }​    if (match(word, bigReg) || match(word, smallReg)) {        return true;   }​    if (match(word.slice(0, 1), bigReg) && match(word.slice(1), smallReg)) {        return true;   }​    return false;};​" 5 | 6 | // console.log(beautyJs(ori, { indent_size: 2, space_in_empty_paren: true })); 7 | 8 | 9 | // $(".CodeMirror-line").text() 10 | 11 | // (function(){ 12 | // // 'use strict' 13 | // var a = b = 5; 14 | // })() 15 | // 16 | 17 | var fs = require('fs'); 18 | var obj = { 19 | index:1, 20 | title: '二叉树展开为链表', 21 | href: 'https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list', 22 | } 23 | 24 | function createFile(obj) { 25 | //已解决的页面。 26 | obj.codeHref = obj.href + '/submissions/'; 27 | var fileName = obj.href.split('https://leetcode-cn.com/problems/')[1]; 28 | //使用中文名+链接中的英文命名 29 | var folderName = 'Algorithms/'+obj.index+obj.title  +  fileName; 30 | if (!fs.existsSync(folderName)) { 31 | fs.mkdirSync(folderName) 32 | } 33 | 34 | 35 | 36 | fs.writeFile(folderName + "/" + fileName + ".js", beautyJs(ori, { 37 | indent_size: 2, 38 | space_in_empty_paren: true 39 | }), function() {}); 40 | 41 | 42 | } 43 | 44 | createFile(obj); 45 | // 46 | 47 | (async() => { 48 | return; 49 | //用于加载页面。 50 | const puppeteer = require('puppeteer'); 51 | const url = 'https://leetcode-cn.com/problems/pascals-triangle-ii/submissions/1'; 52 | const browser = await puppeteer.launch(); 53 | const page = await browser.newPage(); 54 | //到登录页面 55 | await page.goto(url); 56 | 57 | await page.screenshot({ 58 | path: 'page1.png' 59 | }); //截个图 60 | //等待页面加载出来,等同于window.onload 61 | // await page.waitForNavigation({ 62 | // waitUntil: 'load' 63 | // }); 64 | 65 | // await page.goto(url); 66 | //延迟2s等页面内容加载出来。 67 | // await timeout(2000); 68 | 69 | // await page.screenshot({ 70 | // path: 'page2.png' 71 | // }); //截个图 72 | 73 | //获取url。 74 | // const html = await page.$eval('body', e => e.outerHTML); 75 | await browser.close(); 76 | 77 | })() 78 | 79 | 80 | //一个简单的延时。 81 | function timeout(inteval) { 82 | return new Promise(function(resolve, reject) { 83 | setTimeout(function() { 84 | resolve() 85 | }, inteval); 86 | }) 87 | } 88 | --------------------------------------------------------------------------------