├── .editorconfig ├── .prettierrc.js ├── .vscode └── settings.json ├── 1.two-sum.js ├── 1.两数之和.js ├── 10.正则表达式匹配.js ├── 1007.行相等的最少多米诺旋转.js ├── 101.对称二叉树.js ├── 102.二叉树的层次遍历.js ├── 104.二叉树的最大深度.js ├── 105.从前序与中序遍历序列构造二叉树.js ├── 106.从中序与后序遍历序列构造二叉树.js ├── 107.二叉树的层次遍历-ii.js ├── 108.将有序数组转换为二叉搜索树.js ├── 11.盛最多水的容器.js ├── 110.平衡二叉树.js ├── 112.路径总和.js ├── 118.杨辉三角.js ├── 119.杨辉三角-ii.js ├── 12.整数转罗马数字.js ├── 121.买卖股票的最佳时机.js ├── 122.买卖股票的最佳时机-ii.js ├── 124.二叉树中的最大路径和.js ├── 125.验证回文串.js ├── 13.罗马数字转整数.js ├── 136.只出现一次的数字.js ├── 138.复制带随机指针的链表.js ├── 14.最长公共前缀.js ├── 141.linked-list-cycle.js ├── 141.环形链表.js ├── 142.环形链表-ii.js ├── 144.二叉树的前序遍历.js ├── 145.二叉树的后序遍历.js ├── 146.lru缓存机制.js ├── 148.排序链表.js ├── 15.三数之和.js ├── 151.翻转字符串里的单词.js ├── 153.寻找旋转排序数组中的最小值.js ├── 154.寻找旋转排序数组中的最小值-ii.js ├── 155.最小栈.js ├── 16.最接近的三数之和.js ├── 160.相交链表.js ├── 162.寻找峰值.js ├── 167.两数之和-ii-输入有序数组.js ├── 169.多数元素.js ├── 169.求众数.js ├── 17.电话号码的字母组合.js ├── 171.excel表列序号.js ├── 172.阶乘后的零.js ├── 173.二叉搜索树迭代器.js ├── 189.旋转数组.js ├── 19.remove-nth-node-from-end-of-list.js ├── 19.删除链表的倒数第n个节点.js ├── 190.颠倒二进制位.js ├── 191.位-1-的个数.js ├── 198.打家劫舍.js ├── 2.add-two-numbers.js ├── 2.两数相加.js ├── 20.有效的括号.js ├── 200.岛屿数量.js ├── 202.快乐数.js ├── 203.移除链表元素.js ├── 204.计数质数.js ├── 206.reverse-linked-list.js ├── 206.反转链表.js ├── 209.长度最小的子数组.js ├── 21.merge-two-sorted-lists.js ├── 21.合并两个有序链表.js ├── 215.数组中的第k个最大元素.js ├── 217.存在重复元素.js ├── 22.括号生成.js ├── 220.存在重复元素-iii.js ├── 225.用队列实现栈.js ├── 23.合并k个排序链表.js ├── 230.二叉搜索树中第k小的元素.js ├── 231.2-的幂.js ├── 232.用栈实现队列.js ├── 234.回文链表.js ├── 235.二叉搜索树的最近公共祖先.js ├── 236.二叉树的最近公共祖先.js ├── 237.删除链表中的节点.js ├── 238.除自身以外数组的乘积.js ├── 24.两两交换链表中的节点.js ├── 242.有效的字母异位词.js ├── 25.k-个一组翻转链表.js ├── 26.删除排序数组中的重复项.js ├── 268.缺失数字.js ├── 27.移除元素.js ├── 278.第一个错误的版本.js ├── 279.完全平方数.js ├── 28.实现-str-str.js ├── 283.移动零.js ├── 287.寻找重复数.js ├── 29.两数相除.js ├── 292.nim-游戏.js ├── 3.无重复字符的最长子串.js ├── 300.最长上升子序列.js ├── 326.3-的幂.js ├── 328.奇偶链表.js ├── 33.搜索旋转排序数组.js ├── 34.在排序数组中查找元素的第一个和最后一个位置.js ├── 344.反转字符串.js ├── 35.搜索插入位置.js ├── 350.两个数组的交集-ii.js ├── 371.两整数之和.js ├── 374.猜数字大小.js ├── 38.报数.js ├── 387.字符串中的第一个唯一字符.js ├── 4.median-of-two-sorted-arrays.js ├── 4.寻找两个有序数组的中位数.js ├── 41.缺失的第一个正数.js ├── 412.fizz-buzz.js ├── 415.字符串相加.js ├── 43.字符串相乘.js ├── 430.扁平化多级双向链表.js ├── 450.删除二叉搜索树中的节点.js ├── 46.全排列.js ├── 485.最大连续-1-的个数.js ├── 498.对角线遍历.js ├── 5.最长回文子串.js ├── 50.pow-x-n.js ├── 51.n皇后.js ├── 53.最大子序和.js ├── 54.螺旋矩阵.js ├── 557.反转字符串中的单词-iii.js ├── 561.数组拆分-i.js ├── 59.螺旋矩阵-ii.js ├── 599.两个列表的最小索引总和.js ├── 6.z-字形变换.js ├── 60.第k个排列.js ├── 61.旋转链表.js ├── 617.合并二叉树.js ├── 62.不同路径.js ├── 622.设计循环队列.js ├── 658.找到-k-个最接近的元素.js ├── 66.加一.js ├── 67.二进制求和.js ├── 69.x-的平方根.js ├── 7.整数反转.js ├── 70.爬楼梯.js ├── 700.二叉搜索树中的搜索.js ├── 701.二叉搜索树中的插入操作.js ├── 703.数据流中的第k大元素.js ├── 704.二分查找.js ├── 707.设计链表.js ├── 721.账户合并.js ├── 724.寻找数组的中心索引.js ├── 747.至少是其他数字两倍的最大数.js ├── 75.颜色分类.js ├── 752.打开转盘锁.js ├── 78.子集.js ├── 8.字符串转换整数-atoi.js ├── 876.middle-of-the-linked-list.js ├── 88.合并两个有序数组.js ├── 89.格雷编码.js ├── 9.回文数.js ├── 94.二叉树的中序遍历.js ├── 98.验证二叉搜索树.js ├── LICENSE └── README.md /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | // Prettier configuration 2 | // https://prettier.io/docs/en/configuration.html 3 | module.exports = { 4 | singleQuote: true, 5 | semi: false, 6 | trailingComma: 'es5', 7 | arrowParens: 'avoid', 8 | jsxBracketSameLine: true, 9 | } 10 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "prettier.singleQuote": true, 3 | "prettier.semi": false 4 | } -------------------------------------------------------------------------------- /1.two-sum.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=1 lang=javascript 3 | * 4 | * [1] Two Sum 5 | */ 6 | /** 7 | * @param {number[]} nums 8 | * @param {number} target 9 | * @return {number[]} 10 | */ 11 | const twoSum = (nums, target) => { 12 | const map = {} 13 | 14 | for (let i = 0; i < nums.length; i++) { 15 | const another = target - nums[i] 16 | 17 | if (another in map) { 18 | return [map[another], i] 19 | } 20 | 21 | map[nums[i]] = i 22 | } 23 | 24 | return null 25 | } 26 | -------------------------------------------------------------------------------- /1.两数之和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1 lang=javascript 3 | * 4 | * [1] 两数之和 5 | * 6 | * https://leetcode-cn.com/problems/two-sum/description/ 7 | * 8 | * algorithms 9 | * Easy (46.56%) 10 | * Likes: 6196 11 | * Dislikes: 0 12 | * Total Accepted: 540.2K 13 | * Total Submissions: 1.2M 14 | * Testcase Example: '[2,7,11,15]\n9' 15 | * 16 | * 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 17 | * 18 | * 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 19 | * 20 | * 示例: 21 | * 22 | * 给定 nums = [2, 7, 11, 15], target = 9 23 | * 24 | * 因为 nums[0] + nums[1] = 2 + 7 = 9 25 | * 所以返回 [0, 1] 26 | * 27 | * 28 | */ 29 | 30 | // @lc code=start 31 | /** 32 | * @param {number[]} nums 33 | * @param {number} target 34 | * @return {number[]} 35 | */ 36 | const twoSum = (nums, target) => { 37 | const hash = {} 38 | 39 | for (let i = 0; i < nums.length; i++) { 40 | if (hash[target - nums[i]] !== undefined) { 41 | return [hash[target - nums[i]], i] 42 | } else { 43 | hash[nums[i]] = i 44 | } 45 | } 46 | 47 | return [] 48 | } 49 | // @lc code=end 50 | -------------------------------------------------------------------------------- /10.正则表达式匹配.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=10 lang=javascript 3 | * 4 | * [10] 正则表达式匹配 5 | * 6 | * https://leetcode-cn.com/problems/regular-expression-matching/description/ 7 | * 8 | * algorithms 9 | * Hard (25.24%) 10 | * Likes: 740 11 | * Dislikes: 0 12 | * Total Accepted: 37.2K 13 | * Total Submissions: 147.1K 14 | * Testcase Example: '"aa"\n"a"' 15 | * 16 | * 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。 17 | * 18 | * '.' 匹配任意单个字符 19 | * '*' 匹配零个或多个前面的那一个元素 20 | * 21 | * 22 | * 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。 23 | * 24 | * 说明: 25 | * 26 | * 27 | * s 可能为空,且只包含从 a-z 的小写字母。 28 | * p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。 29 | * 30 | * 31 | * 示例 1: 32 | * 33 | * 输入: 34 | * s = "aa" 35 | * p = "a" 36 | * 输出: false 37 | * 解释: "a" 无法匹配 "aa" 整个字符串。 38 | * 39 | * 40 | * 示例 2: 41 | * 42 | * 输入: 43 | * s = "aa" 44 | * p = "a*" 45 | * 输出: true 46 | * 解释: 因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。 47 | * 48 | * 49 | * 示例 3: 50 | * 51 | * 输入: 52 | * s = "ab" 53 | * p = ".*" 54 | * 输出: true 55 | * 解释: ".*" 表示可匹配零个或多个('*')任意字符('.')。 56 | * 57 | * 58 | * 示例 4: 59 | * 60 | * 输入: 61 | * s = "aab" 62 | * p = "c*a*b" 63 | * 输出: true 64 | * 解释: 因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。 65 | * 66 | * 67 | * 示例 5: 68 | * 69 | * 输入: 70 | * s = "mississippi" 71 | * p = "mis*is*p*." 72 | * 输出: false 73 | * 74 | */ 75 | 76 | // @lc code=start 77 | /** 78 | * @param {string} s 79 | * @param {string} p 80 | * @return {boolean} 81 | */ 82 | // TODO: 83 | const isMatch = (s, p) => { 84 | var lenS = s.length 85 | var lenP = p.length 86 | var map = {} 87 | 88 | return check(0, 0) 89 | 90 | function check(idxS, idxP) { 91 | if (map[idxS + ':' + idxP] !== undefined) return map[idxS + ':' + idxP] 92 | if (idxS > lenS) return false 93 | if (idxS === lenS && idxP === lenP) return true 94 | 95 | if (p[idxP] === '.' || p[idxP] === s[idxS]) { 96 | map[idxS + ':' + idxP] = 97 | p[idxP + 1] === '*' 98 | ? check(idxS + 1, idxP) || check(idxS, idxP + 2) 99 | : check(idxS + 1, idxP + 1) 100 | } else { 101 | map[idxS + ':' + idxP] = 102 | p[idxP + 1] === '*' ? check(idxS, idxP + 2) : false 103 | } 104 | return map[idxS + ':' + idxP] 105 | } 106 | } 107 | // @lc code=end 108 | -------------------------------------------------------------------------------- /1007.行相等的最少多米诺旋转.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1007 lang=javascript 3 | * 4 | * [1007] 行相等的最少多米诺旋转 5 | * 6 | * https://leetcode-cn.com/problems/minimum-domino-rotations-for-equal-row/description/ 7 | * 8 | * algorithms 9 | * Medium (39.23%) 10 | * Likes: 8 11 | * Dislikes: 0 12 | * Total Accepted: 1.2K 13 | * Total Submissions: 3K 14 | * Testcase Example: '[2,1,2,4,2,2]\n[5,2,6,2,3,2]' 15 | * 16 | * 在一排多米诺骨牌中,A[i] 和 B[i] 分别代表第 i 个多米诺骨牌的上半部分和下半部分。(一个多米诺是两个从 1 到 6 的数字同列平铺形成的 17 | * —— 该平铺的每一半上都有一个数字。) 18 | * 19 | * 我们可以旋转第 i 张多米诺,使得 A[i] 和 B[i] 的值交换。 20 | * 21 | * 返回能使 A 中所有值或者 B 中所有值都相同的最小旋转次数。 22 | * 23 | * 如果无法做到,返回 -1. 24 | * 25 | * 26 | * 27 | * 示例 1: 28 | * 29 | * 30 | * 31 | * 输入:A = [2,1,2,4,2,2], B = [5,2,6,2,3,2] 32 | * 输出:2 33 | * 解释: 34 | * 图一表示:在我们旋转之前, A 和 B 给出的多米诺牌。 35 | * 如果我们旋转第二个和第四个多米诺骨牌,我们可以使上面一行中的每个值都等于 2,如图二所示。 36 | * 37 | * 38 | * 示例 2: 39 | * 40 | * 输入:A = [3,5,1,2,3], B = [3,6,3,3,4] 41 | * 输出:-1 42 | * 解释: 43 | * 在这种情况下,不可能旋转多米诺牌使一行的值相等。 44 | * 45 | * 46 | * 47 | * 48 | * 提示: 49 | * 50 | * 51 | * 1 <= A[i], B[i] <= 6 52 | * 2 <= A.length == B.length <= 20000 53 | * 54 | * 55 | */ 56 | 57 | // @lc code=start 58 | /** 59 | * @param {number[]} A 60 | * @param {number[]} B 61 | * @return {number} 62 | */ 63 | var minDominoRotations = function (A, B) {} 64 | // @lc code=end 65 | -------------------------------------------------------------------------------- /101.对称二叉树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=101 lang=javascript 3 | * 4 | * [101] 对称二叉树 5 | * 6 | * https://leetcode-cn.com/problems/symmetric-tree/description/ 7 | * 8 | * algorithms 9 | * Easy (48.11%) 10 | * Likes: 446 11 | * Dislikes: 0 12 | * Total Accepted: 55.4K 13 | * Total Submissions: 114.4K 14 | * Testcase Example: '[1,2,2,3,4,4,3]' 15 | * 16 | * 给定一个二叉树,检查它是否是镜像对称的。 17 | * 18 | * 例如,二叉树 [1,2,2,3,4,4,3] 是对称的。 19 | * 20 | * ⁠ 1 21 | * ⁠ / \ 22 | * ⁠ 2 2 23 | * ⁠/ \ / \ 24 | * 3 4 4 3 25 | * 26 | * 27 | * 但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的: 28 | * 29 | * ⁠ 1 30 | * ⁠ / \ 31 | * ⁠ 2 2 32 | * ⁠ \ \ 33 | * ⁠ 3 3 34 | * 35 | * 36 | * 说明: 37 | * 38 | * 如果你可以运用递归和迭代两种方法解决这个问题,会很加分。 39 | * 40 | */ 41 | /** 42 | * Definition for a binary tree node. 43 | * function TreeNode(val) { 44 | * this.val = val; 45 | * this.left = this.right = null; 46 | * } 47 | */ 48 | 49 | const isSymmetricalTree = (node1, node2) => { 50 | if (!node1 && !node2) { 51 | return true 52 | } 53 | 54 | if (!node1 || !node2) { 55 | return false 56 | } 57 | 58 | if (node1.val !== node2.val) { 59 | return false 60 | } 61 | 62 | return ( 63 | isSymmetricalTree(node1.left, node2.right) && 64 | isSymmetricalTree(node1.right, node2.left) 65 | ) 66 | } 67 | 68 | /** 69 | * @param {TreeNode} root 70 | * @return {boolean} 71 | */ 72 | const isSymmetric = root => { 73 | return isSymmetricalTree(root, root) 74 | } 75 | -------------------------------------------------------------------------------- /102.二叉树的层次遍历.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=102 lang=javascript 3 | * 4 | * [102] 二叉树的层次遍历 5 | * 6 | * https://leetcode-cn.com/problems/binary-tree-level-order-traversal/description/ 7 | * 8 | * algorithms 9 | * Medium (58.30%) 10 | * Likes: 275 11 | * Dislikes: 0 12 | * Total Accepted: 44.8K 13 | * Total Submissions: 76.2K 14 | * Testcase Example: '[3,9,20,null,null,15,7]' 15 | * 16 | * 给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。 17 | * 18 | * 例如: 19 | * 给定二叉树: [3,9,20,null,null,15,7], 20 | * 21 | * ⁠ 3 22 | * ⁠ / \ 23 | * ⁠ 9 20 24 | * ⁠ / \ 25 | * ⁠ 15 7 26 | * 27 | * 28 | * 返回其层次遍历结果: 29 | * 30 | * [ 31 | * ⁠ [3], 32 | * ⁠ [9,20], 33 | * ⁠ [15,7] 34 | * ] 35 | * 36 | * 37 | */ 38 | /** 39 | * Definition for a binary tree node. 40 | * function TreeNode(val) { 41 | * this.val = val; 42 | * this.left = this.right = null; 43 | * } 44 | */ 45 | /** 46 | * @param {TreeNode} root 47 | * @return {number[][]} 48 | */ 49 | const levelOrder = root => { 50 | if (!root) { 51 | return [] 52 | } 53 | 54 | let result = [] 55 | let queue = [root] 56 | 57 | while (queue.length) { 58 | let arr = [] 59 | let temp = [] 60 | 61 | while (queue.length) { 62 | let curr = queue.shift() 63 | arr.push(curr.val) 64 | 65 | if (curr.left) { 66 | temp.push(curr.left) 67 | } 68 | 69 | if (curr.right) { 70 | temp.push(curr.right) 71 | } 72 | } 73 | 74 | queue = temp 75 | result.push(arr) 76 | } 77 | 78 | return result 79 | } 80 | -------------------------------------------------------------------------------- /104.二叉树的最大深度.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=104 lang=javascript 3 | * 4 | * [104] 二叉树的最大深度 5 | */ 6 | /** 7 | * Definition for a binary tree node. 8 | * function TreeNode(val) { 9 | * this.val = val; 10 | * this.left = this.right = null; 11 | * } 12 | */ 13 | /** 14 | * @param {TreeNode} root 15 | * @return {number} 16 | */ 17 | const maxDepth = root => { 18 | return !root ? 0 : Math.max(maxDepth(root.left), maxDepth(root.right)) + 1 19 | } 20 | -------------------------------------------------------------------------------- /105.从前序与中序遍历序列构造二叉树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=105 lang=javascript 3 | * 4 | * [105] 从前序与中序遍历序列构造二叉树 5 | * 6 | * https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/ 7 | * 8 | * algorithms 9 | * Medium (62.68%) 10 | * Likes: 276 11 | * Dislikes: 0 12 | * Total Accepted: 31.7K 13 | * Total Submissions: 50.6K 14 | * Testcase Example: '[3,9,20,15,7]\n[9,3,15,20,7]' 15 | * 16 | * 根据一棵树的前序遍历与中序遍历构造二叉树。 17 | * 18 | * 注意: 19 | * 你可以假设树中没有重复的元素。 20 | * 21 | * 例如,给出 22 | * 23 | * 前序遍历 preorder = [3,9,20,15,7] 24 | * 中序遍历 inorder = [9,3,15,20,7] 25 | * 26 | * 返回如下的二叉树: 27 | * 28 | * ⁠ 3 29 | * ⁠ / \ 30 | * ⁠ 9 20 31 | * ⁠ / \ 32 | * ⁠ 15 7 33 | * 34 | */ 35 | 36 | // @lc code=start 37 | /** 38 | * Definition for a binary tree node. 39 | * function TreeNode(val) { 40 | * this.val = val; 41 | * this.left = this.right = null; 42 | * } 43 | */ 44 | /** 45 | * @param {number[]} preorder 46 | * @param {number[]} inorder 47 | * @return {TreeNode} 48 | */ 49 | const buildTree = (preorder, inorder) => { 50 | if (preorder.length === 0) { 51 | return null 52 | } 53 | 54 | if (preorder.length === 1) { 55 | return new TreeNode(preorder[0]) 56 | } 57 | 58 | const value = preorder[0] 59 | const index = inorder.indexOf(value) 60 | 61 | const vinLeft = inorder.slice(0, index) 62 | const vinRight = inorder.slice(index + 1) 63 | 64 | const preLeft = preorder.slice(1, index + 1) 65 | const preRight = preorder.slice(index + 1) 66 | 67 | const node = new TreeNode(value) 68 | 69 | node.left = buildTree(preLeft, vinLeft) 70 | node.right = buildTree(preRight, vinRight) 71 | 72 | return node 73 | } 74 | // @lc code=end 75 | -------------------------------------------------------------------------------- /106.从中序与后序遍历序列构造二叉树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=106 lang=javascript 3 | * 4 | * [106] 从中序与后序遍历序列构造二叉树 5 | * 6 | * https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/description/ 7 | * 8 | * algorithms 9 | * Medium (65.18%) 10 | * Likes: 129 11 | * Dislikes: 0 12 | * Total Accepted: 17.9K 13 | * Total Submissions: 27.5K 14 | * Testcase Example: '[9,3,15,20,7]\n[9,15,7,20,3]' 15 | * 16 | * 根据一棵树的中序遍历与后序遍历构造二叉树。 17 | * 18 | * 注意: 19 | * 你可以假设树中没有重复的元素。 20 | * 21 | * 例如,给出 22 | * 23 | * 中序遍历 inorder = [9,3,15,20,7] 24 | * 后序遍历 postorder = [9,15,7,20,3] 25 | * 26 | * 返回如下的二叉树: 27 | * 28 | * ⁠ 3 29 | * ⁠ / \ 30 | * ⁠ 9 20 31 | * ⁠ / \ 32 | * ⁠ 15 7 33 | * 34 | * 35 | */ 36 | 37 | // @lc code=start 38 | /** 39 | * Definition for a binary tree node. 40 | * function TreeNode(val) { 41 | * this.val = val; 42 | * this.left = this.right = null; 43 | * } 44 | */ 45 | /** 46 | * @param {number[]} inorder 47 | * @param {number[]} postorder 48 | * @return {TreeNode} 49 | */ 50 | 51 | // TODO: 52 | const helper = (inorder, postorder, toInorder, low, high) => { 53 | if (low > high) { 54 | return null 55 | } 56 | 57 | const val = postorder[high] 58 | const node = new TreeNode(val) 59 | 60 | if (low < high) { 61 | let leftSize = 0 62 | 63 | while (toInorder[postorder[low + leftSize]] < toInorder[val]) { 64 | leftSize++ 65 | } 66 | 67 | node.left = helper(inorder, postorder, toInorder, low, low + leftSize - 1) 68 | node.right = helper(inorder, postorder, toInorder, low + leftSize, high - 1) 69 | } 70 | 71 | return node 72 | } 73 | 74 | const buildTree = (inorder, postorder) => { 75 | if (!inorder.length) { 76 | return null 77 | } 78 | 79 | const toInorder = inorder.reduce((map, a, i) => ((map[a] = i), map), {}) 80 | 81 | return helper(inorder, postorder, toInorder, 0, postorder.length - 1) 82 | } 83 | // @lc code=end 84 | -------------------------------------------------------------------------------- /107.二叉树的层次遍历-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=107 lang=javascript 3 | * 4 | * [107] 二叉树的层次遍历 II 5 | * 6 | * https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/description/ 7 | * 8 | * algorithms 9 | * Easy (63.17%) 10 | * Likes: 157 11 | * Dislikes: 0 12 | * Total Accepted: 31.9K 13 | * Total Submissions: 50.6K 14 | * Testcase Example: '[3,9,20,null,null,15,7]' 15 | * 16 | * 给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) 17 | * 18 | * 例如: 19 | * 给定二叉树 [3,9,20,null,null,15,7], 20 | * 21 | * ⁠ 3 22 | * ⁠ / \ 23 | * ⁠ 9 20 24 | * ⁠ / \ 25 | * ⁠ 15 7 26 | * 27 | * 28 | * 返回其自底向上的层次遍历为: 29 | * 30 | * [ 31 | * ⁠ [15,7], 32 | * ⁠ [9,20], 33 | * ⁠ [3] 34 | * ] 35 | * 36 | * 37 | */ 38 | 39 | // @lc code=start 40 | /** 41 | * Definition for a binary tree node. 42 | * function TreeNode(val) { 43 | * this.val = val; 44 | * this.left = this.right = null; 45 | * } 46 | */ 47 | /** 48 | * @param {TreeNode} root 49 | * @return {number[][]} 50 | */ 51 | var levelOrderBottom = function (root) { 52 | if (root == null) { 53 | return [] 54 | } 55 | let queue = [] 56 | let results = [] 57 | queue.push(root) 58 | while (queue.length > 0) { 59 | /* level-order traversal */ 60 | let level = [] /* collect node.vals for current level */ 61 | let size = 62 | queue.length /* instead of using recursion, we will use a loop bounded by the queue size */ 63 | while (size > 0) { 64 | let current = queue.shift() /* remove and capture next item from queue */ 65 | level.push([ 66 | current.val, 67 | ]) /* add the current val to the current level array */ 68 | 69 | /* if we have a left or right subtree, explore */ 70 | if (current.left != null) { 71 | queue.push(current.left) 72 | } 73 | 74 | if (current.right != null) { 75 | queue.push(current.right) 76 | } 77 | 78 | size-- /* level complete, decrement size and proceed */ 79 | } 80 | 81 | results.push(level) /* push the last level's results */ 82 | } 83 | return results.reverse() /* return results, in reverse order */ 84 | } 85 | // @lc code=end 86 | -------------------------------------------------------------------------------- /108.将有序数组转换为二叉搜索树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=108 lang=javascript 3 | * 4 | * [108] 将有序数组转换为二叉搜索树 5 | */ 6 | /** 7 | * Definition for a binary tree node. 8 | * function TreeNode(val) { 9 | * this.val = val; 10 | * this.left = this.right = null; 11 | * } 12 | */ 13 | /** 14 | * @param {number[]} nums 15 | * @return {TreeNode} 16 | */ 17 | const sortedArrayToBST = function (nums) { 18 | if (nums.length === 0) { 19 | return null 20 | } 21 | 22 | let mid = Math.floor(nums.length / 2) 23 | 24 | const node = new TreeNode(nums[mid]) 25 | 26 | node.left = sortedArrayToBST(nums.slice(0, mid)) 27 | node.right = sortedArrayToBST(nums.slice(mid + 1)) 28 | 29 | return node 30 | } 31 | -------------------------------------------------------------------------------- /11.盛最多水的容器.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=11 lang=javascript 3 | * 4 | * [11] 盛最多水的容器 5 | * 6 | * https://leetcode-cn.com/problems/container-with-most-water/description/ 7 | * 8 | * algorithms 9 | * Medium (57.40%) 10 | * Likes: 822 11 | * Dislikes: 0 12 | * Total Accepted: 84.9K 13 | * Total Submissions: 146.3K 14 | * Testcase Example: '[1,8,6,2,5,4,8,3,7]' 15 | * 16 | * 给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 17 | * (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 18 | * 19 | * 说明:你不能倾斜容器,且 n 的值至少为 2。 20 | * 21 | * 22 | * 23 | * 图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。 24 | * 25 | * 26 | * 27 | * 示例: 28 | * 29 | * 输入: [1,8,6,2,5,4,8,3,7] 30 | * 输出: 49 31 | * 32 | */ 33 | 34 | // @lc code=start 35 | /** 36 | * @param {number[]} height 37 | * @return {number} 38 | */ 39 | 40 | // 暴力法 41 | const maxArea1 = height => { 42 | let maxArea = 0 43 | 44 | for (let i = 0; i < height.length; i++) { 45 | for (let j = i + 1; j < height.length; j++) { 46 | maxArea = Math.max(maxArea, Math.min(height[i], height[j]) * (j - i)) 47 | } 48 | } 49 | 50 | return maxArea 51 | } 52 | 53 | // 双指针法 54 | const maxArea = height => { 55 | let area = 0 56 | 57 | let left = 0 58 | let right = height.length - 1 59 | 60 | while (left < right) { 61 | const currArea = Math.min(height[left], height[right]) * (right - left) 62 | 63 | area = Math.max(area, currArea) 64 | 65 | if (height[left] < height[right]) { 66 | left++ 67 | } else { 68 | right-- 69 | } 70 | } 71 | 72 | return area 73 | } 74 | // @lc code=end 75 | -------------------------------------------------------------------------------- /110.平衡二叉树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=110 lang=javascript 3 | * 4 | * [110] 平衡二叉树 https://leetcode-cn.com/problems/balanced-binary-tree/ 5 | */ 6 | /** 7 | * Definition for a binary tree node. 8 | * function TreeNode(val) { 9 | * this.val = val; 10 | * this.left = this.right = null; 11 | * } 12 | */ 13 | /** 14 | * @param {TreeNode} root 15 | * @return {boolean} 16 | */ 17 | const isBalanced = root => { 18 | return balanced(root) !== -1 19 | } 20 | 21 | const balanced = node => { 22 | if (!node) { 23 | return 0 24 | } 25 | 26 | const left = balanced(node.left) 27 | const right = balanced(node.right) 28 | 29 | if (left === -1 || right === -1 || Math.abs(left - right) > 1) { 30 | return -1 31 | } 32 | 33 | return Math.max(left, right) + 1 34 | } 35 | -------------------------------------------------------------------------------- /112.路径总和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=112 lang=javascript 3 | * 4 | * [112] 路径总和 5 | * 6 | * https://leetcode-cn.com/problems/path-sum/description/ 7 | * 8 | * algorithms 9 | * Easy (48.28%) 10 | * Likes: 195 11 | * Dislikes: 0 12 | * Total Accepted: 38.9K 13 | * Total Submissions: 80.7K 14 | * Testcase Example: '[5,4,8,11,null,13,4,7,2,null,null,null,1]\n22' 15 | * 16 | * 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。 17 | * 18 | * 说明: 叶子节点是指没有子节点的节点。 19 | * 20 | * 示例: 21 | * 给定如下二叉树,以及目标和 sum = 22, 22 | * 23 | * ⁠ 5 24 | * ⁠ / \ 25 | * ⁠ 4 8 26 | * ⁠ / / \ 27 | * ⁠ 11 13 4 28 | * ⁠ / \ \ 29 | * ⁠ 7 2 1 30 | * 31 | * 32 | * 返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。 33 | * 34 | */ 35 | 36 | // @lc code=start 37 | /** 38 | * Definition for a binary tree node. 39 | * function TreeNode(val) { 40 | * this.val = val; 41 | * this.left = this.right = null; 42 | * } 43 | */ 44 | /** 45 | * @param {TreeNode} root 46 | * @param {number} sum 47 | * @return {boolean} 48 | */ 49 | // TODO: 回溯算法 50 | 51 | const hasPathSumCore = (node, expectNumber, stack, sum, result) => { 52 | stack.push(node.val) 53 | sum += node.val 54 | 55 | if (!node.left && !node.right && sum === expectNumber) { 56 | result.push(stack.slice(0)) 57 | } 58 | 59 | if (node.left) { 60 | hasPathSumCore(node.left, expectNumber, stack, sum, result) 61 | } 62 | 63 | if (node.right) { 64 | hasPathSumCore(node.right, expectNumber, stack, sum, result) 65 | } 66 | 67 | stack.pop() 68 | } 69 | 70 | const hasPathSum = (root, sum) => { 71 | const result = [] 72 | 73 | if (root) { 74 | hasPathSumCore(root, sum, [], 0, result) 75 | } 76 | 77 | return result 78 | } 79 | // @lc code=end 80 | -------------------------------------------------------------------------------- /118.杨辉三角.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=118 lang=javascript 3 | * 4 | * [118] 杨辉三角 5 | * 6 | * https://leetcode-cn.com/problems/pascals-triangle/description/ 7 | * 8 | * algorithms 9 | * Easy (63.68%) 10 | * Likes: 189 11 | * Dislikes: 0 12 | * Total Accepted: 37.4K 13 | * Total Submissions: 58.4K 14 | * Testcase Example: '5' 15 | * 16 | * 给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。 17 | * 18 | * 19 | * 20 | * 在杨辉三角中,每个数是它左上方和右上方的数的和。 21 | * 22 | * 示例: 23 | * 24 | * 输入: 5 25 | * 输出: 26 | * [ 27 | * ⁠ [1], 28 | * ⁠ [1,1], 29 | * ⁠ [1,2,1], 30 | * ⁠ [1,3,3,1], 31 | * ⁠[1,4,6,4,1] 32 | * ] 33 | * 34 | */ 35 | /** 36 | * @param {number} numRows 37 | * @return {number[][]} 38 | */ 39 | const generate = numRows => { 40 | if (numRows === 0) { 41 | return [] 42 | } 43 | 44 | const result = [] 45 | 46 | for (let i = 0; i < numRows; i++) { 47 | let currRow = [] 48 | 49 | for (let j = 0; j <= i; j++) { 50 | if (j === 0 || j === i) { 51 | currRow.push(1) 52 | } else { 53 | currRow.push(result[i - 1][j - 1] + result[i - 1][j]) 54 | } 55 | } 56 | 57 | result.push(currRow) 58 | } 59 | 60 | return result 61 | } 62 | -------------------------------------------------------------------------------- /119.杨辉三角-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=119 lang=javascript 3 | * 4 | * [119] 杨辉三角 II 5 | * 6 | * https://leetcode-cn.com/problems/pascals-triangle-ii/description/ 7 | * 8 | * algorithms 9 | * Easy (59.07%) 10 | * Likes: 98 11 | * Dislikes: 0 12 | * Total Accepted: 32.5K 13 | * Total Submissions: 55K 14 | * Testcase Example: '3' 15 | * 16 | * 给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行。 17 | * 18 | * 19 | * 20 | * 在杨辉三角中,每个数是它左上方和右上方的数的和。 21 | * 22 | * 示例: 23 | * 24 | * 输入: 3 25 | * 输出: [1,3,3,1] 26 | * 27 | * 28 | * 进阶: 29 | * 30 | * 你可以优化你的算法到 O(k) 空间复杂度吗? 31 | * 32 | */ 33 | 34 | // @lc code=start 35 | /** 36 | * @param {number} rowIndex 37 | * @return {number[]} 38 | */ 39 | const getRow = function (rowIndex) { 40 | let row = [1] 41 | 42 | for (let i = 1; i <= rowIndex; i++) { 43 | for (let j = i; j > 0; j--) { 44 | if (j === i) { 45 | row[j] = 1 46 | } else { 47 | row[j] = row[j - 1] + row[j] 48 | } 49 | } 50 | } 51 | 52 | return row 53 | } 54 | // @lc code=end 55 | -------------------------------------------------------------------------------- /12.整数转罗马数字.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=12 lang=javascript 3 | * 4 | * [12] 整数转罗马数字 5 | * 6 | * https://leetcode-cn.com/problems/integer-to-roman/description/ 7 | * 8 | * algorithms 9 | * Medium (61.87%) 10 | * Likes: 233 11 | * Dislikes: 0 12 | * Total Accepted: 53.5K 13 | * Total Submissions: 86.5K 14 | * Testcase Example: '3' 15 | * 16 | * 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 17 | * 18 | * 字符 数值 19 | * I 1 20 | * V 5 21 | * X 10 22 | * L 50 23 | * C 100 24 | * D 500 25 | * M 1000 26 | * 27 | * 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + 28 | * II 。 29 | * 30 | * 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 31 | * 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况: 32 | * 33 | * 34 | * I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。 35 | * X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 36 | * C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。 37 | * 38 | * 39 | * 给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。 40 | * 41 | * 示例 1: 42 | * 43 | * 输入: 3 44 | * 输出: "III" 45 | * 46 | * 示例 2: 47 | * 48 | * 输入: 4 49 | * 输出: "IV" 50 | * 51 | * 示例 3: 52 | * 53 | * 输入: 9 54 | * 输出: "IX" 55 | * 56 | * 示例 4: 57 | * 58 | * 输入: 58 59 | * 输出: "LVIII" 60 | * 解释: L = 50, V = 5, III = 3. 61 | * 62 | * 63 | * 示例 5: 64 | * 65 | * 输入: 1994 66 | * 输出: "MCMXCIV" 67 | * 解释: M = 1000, CM = 900, XC = 90, IV = 4. 68 | * 69 | */ 70 | 71 | // TODO: 72 | // @lc code=start 73 | /** 74 | * @param {number} num 75 | * @return {string} 76 | */ 77 | const intToRoman = function (num) { 78 | let digit = '' 79 | let r = '' 80 | 81 | const convert = (digit, tens, fives, ones) => { 82 | if (digit === 9) { 83 | r = r.concat(ones + tens) 84 | } else if (digit > 5) { 85 | r = r.concat(fives + ones.repeat(digit % 5)) 86 | } else if (digit === 5) { 87 | r = r.concat(fives) 88 | } else if (digit === 4) { 89 | r = r.concat(ones + fives) 90 | } else if (digit > 0) { 91 | r = r.concat(ones.repeat(digit)) 92 | } 93 | } 94 | 95 | if (num > 999) { 96 | convert(Math.floor(num / 1000), '', '', 'M') 97 | num = Math.floor(num % 1000) 98 | } 99 | 100 | if (num > 99) { 101 | convert(Math.floor(num / 100), 'M', 'D', 'C') 102 | num = Math.floor(num % 100) 103 | } 104 | 105 | if (num > 9) { 106 | convert(Math.floor(num / 10), 'C', 'L', 'X') 107 | num = Math.floor(num % 10) 108 | } 109 | 110 | convert(num, 'X', 'V', 'I') 111 | 112 | return r 113 | } 114 | // @lc code=end 115 | -------------------------------------------------------------------------------- /121.买卖股票的最佳时机.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=121 lang=javascript 3 | * 4 | * [121] 买卖股票的最佳时机 5 | * 6 | * https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/description/ 7 | * 8 | * algorithms 9 | * Easy (50.50%) 10 | * Likes: 513 11 | * Dislikes: 0 12 | * Total Accepted: 69.1K 13 | * Total Submissions: 136.7K 14 | * Testcase Example: '[7,1,5,3,6,4]' 15 | * 16 | * 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 17 | * 18 | * 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。 19 | * 20 | * 注意你不能在买入股票前卖出股票。 21 | * 22 | * 示例 1: 23 | * 24 | * 输入: [7,1,5,3,6,4] 25 | * 输出: 5 26 | * 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 27 | * ⁠ 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。 28 | * 29 | * 30 | * 示例 2: 31 | * 32 | * 输入: [7,6,4,3,1] 33 | * 输出: 0 34 | * 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。 35 | * 36 | * 37 | */ 38 | /** 39 | * 时间复杂度:O(n) 只需要遍历一次 40 | * 空间复杂度:O(1) 值使用了常数个变量 41 | */ 42 | /** 43 | * @param {number[]} prices 44 | * @return {number} 45 | */ 46 | const maxProfit = prices => { 47 | let min = prices[0] 48 | let result = 0 49 | 50 | for (let i = 0; i < prices.length; i++) { 51 | if (prices[i] > prices[i - 1]) { 52 | result = Math.max(result, prices[i] - min) 53 | } else { 54 | min = Math.min(min, prices[i]) 55 | } 56 | } 57 | 58 | return result 59 | } 60 | -------------------------------------------------------------------------------- /122.买卖股票的最佳时机-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=122 lang=javascript 3 | * 4 | * [122] 买卖股票的最佳时机 II 5 | * 6 | * https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/description/ 7 | * 8 | * algorithms 9 | * Easy (55.04%) 10 | * Likes: 453 11 | * Dislikes: 0 12 | * Total Accepted: 72.6K 13 | * Total Submissions: 131.6K 14 | * Testcase Example: '[7,1,5,3,6,4]' 15 | * 16 | * 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 17 | * 18 | * 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。 19 | * 20 | * 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。 21 | * 22 | * 示例 1: 23 | * 24 | * 输入: [7,1,5,3,6,4] 25 | * 输出: 7 26 | * 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。 27 | * 随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。 28 | * 29 | * 30 | * 示例 2: 31 | * 32 | * 输入: [1,2,3,4,5] 33 | * 输出: 4 34 | * 解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 35 | * 。 36 | * 注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。 37 | * 因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。 38 | * 39 | * 40 | * 示例 3: 41 | * 42 | * 输入: [7,6,4,3,1] 43 | * 输出: 0 44 | * 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。 45 | * 46 | */ 47 | /** 48 | * @param {number[]} prices 49 | * @return {number} 50 | */ 51 | const maxProfit = prices => { 52 | let result = 0 53 | 54 | for (let i = 0; i < prices.length; i++) { 55 | if (prices[i] > prices[i - 1]) { 56 | result = result + prices[i] - prices[i - 1] 57 | } 58 | } 59 | 60 | return result 61 | } 62 | -------------------------------------------------------------------------------- /124.二叉树中的最大路径和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=124 lang=javascript 3 | * 4 | * [124] 二叉树中的最大路径和 5 | * 6 | * https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/description/ 7 | * 8 | * algorithms 9 | * Hard (37.26%) 10 | * Likes: 173 11 | * Dislikes: 0 12 | * Total Accepted: 12K 13 | * Total Submissions: 32.2K 14 | * Testcase Example: '[1,2,3]' 15 | * 16 | * 给定一个非空二叉树,返回其最大路径和。 17 | * 18 | * 本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: [1,2,3] 23 | * 24 | * ⁠ 1 25 | * ⁠ / \ 26 | * ⁠ 2 3 27 | * 28 | * 输出: 6 29 | * 30 | * 31 | * 示例 2: 32 | * 33 | * 输入: [-10,9,20,null,null,15,7] 34 | * 35 | * -10 36 | * / \ 37 | * 9  20 38 | * /  \ 39 | * 15   7 40 | * 41 | * 输出: 42 42 | * 43 | */ 44 | /** 45 | * Definition for a binary tree node. 46 | * function TreeNode(val) { 47 | * this.val = val; 48 | * this.left = this.right = null; 49 | * } 50 | */ 51 | /** 52 | * @param {TreeNode} root 53 | * @return {number} 54 | */ 55 | const maxPathSum = root => { 56 | let max = Math.pow(-2, 31) 57 | 58 | const getMaxSum = node => { 59 | if (!node) { 60 | return 0 61 | } 62 | 63 | const leftSum = getMaxSum(node.left) 64 | const rightSum = getMaxSum(node.right) 65 | 66 | max = Math.max(max, node.val + leftSum + rightSum) 67 | 68 | return Math.max(0, node.val + leftSum, node.val + rightSum) 69 | } 70 | 71 | getMaxSum(root) 72 | 73 | return max 74 | } 75 | -------------------------------------------------------------------------------- /125.验证回文串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=125 lang=javascript 3 | * 4 | * [125] 验证回文串 5 | * 6 | * https://leetcode-cn.com/problems/valid-palindrome/description/ 7 | * 8 | * algorithms 9 | * Easy (40.74%) 10 | * Likes: 119 11 | * Dislikes: 0 12 | * Total Accepted: 54.7K 13 | * Total Submissions: 133.3K 14 | * Testcase Example: '"A man, a plan, a canal: Panama"' 15 | * 16 | * 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。 17 | * 18 | * 说明:本题中,我们将空字符串定义为有效的回文串。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: "A man, a plan, a canal: Panama" 23 | * 输出: true 24 | * 25 | * 26 | * 示例 2: 27 | * 28 | * 输入: "race a car" 29 | * 输出: false 30 | * 31 | * 32 | */ 33 | /** 34 | * @param {string} s 35 | * @return {boolean} 36 | */ 37 | const isPalindrome = s => { 38 | let strippedString = s.replace(/\W/g, '') 39 | let reversedString = strippedString.split('').reverse().join('') 40 | 41 | return strippedString.toLowerCase() == reversedString.toLowerCase() 42 | } 43 | -------------------------------------------------------------------------------- /13.罗马数字转整数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=13 lang=javascript 3 | * 4 | * [13] 罗马数字转整数 5 | * 6 | * https://leetcode-cn.com/problems/roman-to-integer/description/ 7 | * 8 | * algorithms 9 | * Easy (58.86%) 10 | * Likes: 607 11 | * Dislikes: 0 12 | * Total Accepted: 96.7K 13 | * Total Submissions: 163.9K 14 | * Testcase Example: '"III"' 15 | * 16 | * 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 17 | * 18 | * 字符 数值 19 | * I 1 20 | * V 5 21 | * X 10 22 | * L 50 23 | * C 100 24 | * D 500 25 | * M 1000 26 | * 27 | * 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + 28 | * II 。 29 | * 30 | * 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 31 | * 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况: 32 | * 33 | * 34 | * I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。 35 | * X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 36 | * C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。 37 | * 38 | * 39 | * 给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。 40 | * 41 | * 示例 1: 42 | * 43 | * 输入: "III" 44 | * 输出: 3 45 | * 46 | * 示例 2: 47 | * 48 | * 输入: "IV" 49 | * 输出: 4 50 | * 51 | * 示例 3: 52 | * 53 | * 输入: "IX" 54 | * 输出: 9 55 | * 56 | * 示例 4: 57 | * 58 | * 输入: "LVIII" 59 | * 输出: 58 60 | * 解释: L = 50, V= 5, III = 3. 61 | * 62 | * 63 | * 示例 5: 64 | * 65 | * 输入: "MCMXCIV" 66 | * 输出: 1994 67 | * 解释: M = 1000, CM = 900, XC = 90, IV = 4. 68 | * 69 | */ 70 | /** 71 | * @param {string} s 72 | * @return {number} 73 | */ 74 | const map = { 75 | I: 1, 76 | V: 5, 77 | X: 10, 78 | L: 50, 79 | C: 100, 80 | D: 500, 81 | M: 1000, 82 | } 83 | 84 | const romanToInt = function (s) { 85 | let value = 0 86 | 87 | for (let i = 0; i < s.length; i++) { 88 | if (map[s[i]] < map[s[i + 1]]) { 89 | value -= map[s[i]] 90 | } else { 91 | value += map[s[i]] 92 | } 93 | } 94 | 95 | return value 96 | } 97 | -------------------------------------------------------------------------------- /136.只出现一次的数字.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=136 lang=javascript 3 | * 4 | * [136] 只出现一次的数字 5 | * 6 | * https://leetcode-cn.com/problems/single-number/description/ 7 | * 8 | * algorithms 9 | * Easy (62.93%) 10 | * Likes: 820 11 | * Dislikes: 0 12 | * Total Accepted: 97.6K 13 | * Total Submissions: 154.4K 14 | * Testcase Example: '[2,2,1]' 15 | * 16 | * 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 17 | * 18 | * 说明: 19 | * 20 | * 你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗? 21 | * 22 | * 示例 1: 23 | * 24 | * 输入: [2,2,1] 25 | * 输出: 1 26 | * 27 | * 28 | * 示例 2: 29 | * 30 | * 输入: [4,1,2,1,2] 31 | * 输出: 4 32 | * 33 | */ 34 | /** 35 | * @param {number[]} nums 36 | * @return {number} 37 | */ 38 | const singleNumber = nums => { 39 | let list = [] 40 | 41 | for (let i = 0; i < nums.length; i++) { 42 | let index = list.indexOf(nums[i]) 43 | 44 | if (~index) { 45 | list.splice(index, 1) 46 | } else { 47 | list.push(nums[i]) 48 | } 49 | } 50 | 51 | return list.pop() 52 | } 53 | -------------------------------------------------------------------------------- /138.复制带随机指针的链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=138 lang=javascript 3 | * 4 | * [138] 复制带随机指针的链表 5 | * 6 | * https://leetcode-cn.com/problems/copy-list-with-random-pointer/description/ 7 | * 8 | * algorithms 9 | * Medium (38.86%) 10 | * Likes: 155 11 | * Dislikes: 0 12 | * Total Accepted: 14.7K 13 | * Total Submissions: 36.8K 14 | * Testcase Example: '{"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}' 15 | * 16 | * 给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。 17 | * 18 | * 要求返回这个链表的深拷贝。 19 | * 20 | * 21 | * 22 | * 示例: 23 | * 24 | * 25 | * 26 | * 输入: 27 | * 28 | * {"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1} 29 | * 30 | * 解释: 31 | * 节点 1 的值是 1,它的下一个指针和随机指针都指向节点 2 。 32 | * 节点 2 的值是 2,它的下一个指针指向 null,随机指针指向它自己。 33 | * 34 | * 35 | * 36 | * 37 | * 提示: 38 | * 39 | * 40 | * 你必须返回给定头的拷贝作为对克隆列表的引用。 41 | * 42 | * 43 | */ 44 | 45 | // @lc code=start 46 | /** 47 | * // Definition for a Node. 48 | * function Node(val,next,random) { 49 | * this.val = val; 50 | * this.next = next; 51 | * this.random = random; 52 | * }; 53 | */ 54 | // TODO: 55 | /** 56 | * @param {Node} head 57 | * @return {Node} 58 | */ 59 | const copyRandomList = function (head) { 60 | if (!head) { 61 | return null 62 | } 63 | const clones = new Map() 64 | let n = head 65 | 66 | while (n) { 67 | clones.set(n, new Node(n.val)) 68 | n = n.next 69 | } 70 | 71 | n = head 72 | 73 | while (n) { 74 | clones.get(n).next = clones.get(n.next) || null 75 | clones.get(n).random = clones.get(n.random) || null 76 | n = n.next 77 | } 78 | 79 | return clones.get(head) 80 | } 81 | // @lc code=end 82 | -------------------------------------------------------------------------------- /14.最长公共前缀.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=14 lang=javascript 3 | * 4 | * [14] 最长公共前缀 5 | * 6 | * https://leetcode-cn.com/problems/longest-common-prefix/description/ 7 | * 8 | * algorithms 9 | * Easy (34.49%) 10 | * Likes: 684 11 | * Dislikes: 0 12 | * Total Accepted: 117.9K 13 | * Total Submissions: 340K 14 | * Testcase Example: '["flower","flow","flight"]' 15 | * 16 | * 编写一个函数来查找字符串数组中的最长公共前缀。 17 | * 18 | * 如果不存在公共前缀,返回空字符串 ""。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: ["flower","flow","flight"] 23 | * 输出: "fl" 24 | * 25 | * 26 | * 示例 2: 27 | * 28 | * 输入: ["dog","racecar","car"] 29 | * 输出: "" 30 | * 解释: 输入不存在公共前缀。 31 | * 32 | * 33 | * 说明: 34 | * 35 | * 所有输入只包含小写字母 a-z 。 36 | * 37 | */ 38 | /** 39 | * @param {string[]} strs 40 | * @return {string} 41 | */ 42 | const longestCommonPrefix = strs => { 43 | if (!strs || strs.length === 0) { 44 | return '' 45 | } 46 | 47 | return strs.reduce((pre, next) => { 48 | let i = 0 49 | 50 | while (pre[i] && next[i] && pre[i] === next[i]) { 51 | i++ 52 | } 53 | 54 | return pre.slice(0, i) 55 | }) 56 | } 57 | -------------------------------------------------------------------------------- /141.linked-list-cycle.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=141 lang=javascript 3 | * 4 | * [141] Linked List Cycle 5 | */ 6 | /** 7 | * Definition for singly-linked list. 8 | * function ListNode(val) { 9 | * this.val = val; 10 | * this.next = null; 11 | * } 12 | */ 13 | 14 | /** 15 | * @param {ListNode} head 16 | * @return {boolean} 17 | */ 18 | const hasCycle = head => { 19 | if (!head) { 20 | return false 21 | } 22 | 23 | while (head) { 24 | if (head.checked) { 25 | return true 26 | } 27 | head.checked = true 28 | head = head.next 29 | } 30 | 31 | return false 32 | } 33 | -------------------------------------------------------------------------------- /141.环形链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=141 lang=javascript 3 | * 4 | * [141] 环形链表 5 | * 6 | * https://leetcode-cn.com/problems/linked-list-cycle/description/ 7 | * 8 | * algorithms 9 | * Easy (42.37%) 10 | * Likes: 366 11 | * Dislikes: 0 12 | * Total Accepted: 62.2K 13 | * Total Submissions: 145.9K 14 | * Testcase Example: '[3,2,0,-4]\n1' 15 | * 16 | * 给定一个链表,判断链表中是否有环。 17 | * 18 | * 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。 19 | * 20 | * 21 | * 22 | * 示例 1: 23 | * 24 | * 输入:head = [3,2,0,-4], pos = 1 25 | * 输出:true 26 | * 解释:链表中有一个环,其尾部连接到第二个节点。 27 | * 28 | * 29 | * 30 | * 31 | * 示例 2: 32 | * 33 | * 输入:head = [1,2], pos = 0 34 | * 输出:true 35 | * 解释:链表中有一个环,其尾部连接到第一个节点。 36 | * 37 | * 38 | * 39 | * 40 | * 示例 3: 41 | * 42 | * 输入:head = [1], pos = -1 43 | * 输出:false 44 | * 解释:链表中没有环。 45 | * 46 | * 47 | * 48 | * 49 | * 50 | * 51 | * 进阶: 52 | * 53 | * 你能用 O(1)(即,常量)内存解决此问题吗? 54 | * 55 | */ 56 | /** 57 | * Definition for singly-linked list. 58 | * function ListNode(val) { 59 | * this.val = val; 60 | * this.next = null; 61 | * } 62 | */ 63 | 64 | /** 65 | * @param {ListNode} head 66 | * @return {boolean} 67 | */ 68 | const hasCycle = head => { 69 | let slow = head 70 | let fast = head 71 | 72 | while (fast && fast.next) { 73 | slow = slow.next 74 | fast = fast.next.next 75 | 76 | if (slow === fast) { 77 | return true 78 | } 79 | } 80 | 81 | return false 82 | } 83 | -------------------------------------------------------------------------------- /142.环形链表-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=142 lang=javascript 3 | * 4 | * [142] 环形链表 II 5 | * 6 | * https://leetcode-cn.com/problems/linked-list-cycle-ii/description/ 7 | * 8 | * algorithms 9 | * Medium (43.07%) 10 | * Likes: 226 11 | * Dislikes: 0 12 | * Total Accepted: 27.2K 13 | * Total Submissions: 62.7K 14 | * Testcase Example: '[3,2,0,-4]\n1' 15 | * 16 | * 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 17 | * 18 | * 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。 19 | * 20 | * 说明:不允许修改给定的链表。 21 | * 22 | * 23 | * 24 | * 示例 1: 25 | * 26 | * 输入:head = [3,2,0,-4], pos = 1 27 | * 输出:tail connects to node index 1 28 | * 解释:链表中有一个环,其尾部连接到第二个节点。 29 | * 30 | * 31 | * 32 | * 33 | * 示例 2: 34 | * 35 | * 输入:head = [1,2], pos = 0 36 | * 输出:tail connects to node index 0 37 | * 解释:链表中有一个环,其尾部连接到第一个节点。 38 | * 39 | * 40 | * 41 | * 42 | * 示例 3: 43 | * 44 | * 输入:head = [1], pos = -1 45 | * 输出:no cycle 46 | * 解释:链表中没有环。 47 | * 48 | * 49 | * 50 | * 51 | * 52 | * 53 | * 进阶: 54 | * 你是否可以不用额外空间解决此题? 55 | * 56 | */ 57 | /** 58 | * Definition for singly-linked list. 59 | * function ListNode(val) { 60 | * this.val = val; 61 | * this.next = null; 62 | * } 63 | */ 64 | 65 | /** 66 | * @param {ListNode} head 67 | * @return {ListNode} 68 | */ 69 | const detectCycle = head => { 70 | const map = new WeakMap() 71 | 72 | while (head) { 73 | map.set(head, true) 74 | head = head.next 75 | 76 | if (map.has(head)) { 77 | return head 78 | } 79 | } 80 | 81 | return null 82 | } 83 | -------------------------------------------------------------------------------- /144.二叉树的前序遍历.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=144 lang=javascript 3 | * 4 | * [144] 二叉树的前序遍历 5 | * 6 | * https://leetcode-cn.com/problems/binary-tree-preorder-traversal/description/ 7 | * 8 | * algorithms 9 | * Medium (62.39%) 10 | * Likes: 173 11 | * Dislikes: 0 12 | * Total Accepted: 52.4K 13 | * Total Submissions: 83.7K 14 | * Testcase Example: '[1,null,2,3]' 15 | * 16 | * 给定一个二叉树,返回它的 前序 遍历。 17 | * 18 | * 示例: 19 | * 20 | * 输入: [1,null,2,3] 21 | * ⁠ 1 22 | * ⁠ \ 23 | * ⁠ 2 24 | * ⁠ / 25 | * ⁠ 3 26 | * 27 | * 输出: [1,2,3] 28 | * 29 | * 30 | * 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 31 | * 32 | */ 33 | 34 | // @lc code=start 35 | /** 36 | * Definition for a binary tree node. 37 | * function TreeNode(val) { 38 | * this.val = val; 39 | * this.left = this.right = null; 40 | * } 41 | */ 42 | /** 43 | * @param {TreeNode} root 44 | * @return {number[]} 45 | */ 46 | const preorderTraversal = (root, array = []) => { 47 | if (!root) { 48 | return array 49 | } 50 | 51 | array.push(root.val) 52 | preorderTraversal(root.left, array) 53 | preorderTraversal(root.right, array) 54 | 55 | return array 56 | } 57 | // @lc code=end 58 | 59 | // 非递归实现 60 | const preorderTraversal2 = root => { 61 | const result = [] 62 | const stack = [] 63 | 64 | let current = root 65 | 66 | while (current || stack.length > 0) { 67 | while (current) { 68 | result.push(current.val) 69 | stack.push(current) 70 | current = current.left 71 | } 72 | 73 | current = stack.pop() 74 | current = current.right 75 | } 76 | 77 | return result 78 | } 79 | -------------------------------------------------------------------------------- /145.二叉树的后序遍历.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=145 lang=javascript 3 | * 4 | * [145] 二叉树的后序遍历 5 | * 6 | * https://leetcode-cn.com/problems/binary-tree-postorder-traversal/description/ 7 | * 8 | * algorithms 9 | * Hard (68.46%) 10 | * Likes: 189 11 | * Dislikes: 0 12 | * Total Accepted: 39.5K 13 | * Total Submissions: 57.4K 14 | * Testcase Example: '[1,null,2,3]' 15 | * 16 | * 给定一个二叉树,返回它的 后序 遍历。 17 | * 18 | * 示例: 19 | * 20 | * 输入: [1,null,2,3] 21 | * ⁠ 1 22 | * ⁠ \ 23 | * ⁠ 2 24 | * ⁠ / 25 | * ⁠ 3 26 | * 27 | * 输出: [3,2,1] 28 | * 29 | * 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 30 | * 31 | */ 32 | 33 | // @lc code=start 34 | /** 35 | * Definition for a binary tree node. 36 | * function TreeNode(val) { 37 | * this.val = val; 38 | * this.left = this.right = null; 39 | * } 40 | */ 41 | /** 42 | * @param {TreeNode} root 43 | * @return {number[]} 44 | */ 45 | const postorderTraversal = (root, array = []) => { 46 | if (!root) { 47 | return array 48 | } 49 | 50 | postorderTraversal(root.left, array) 51 | postorderTraversal(root.right, array) 52 | array.push(root.val) 53 | 54 | return array 55 | } 56 | // @lc code=end 57 | const postorderTraversal2 = root => { 58 | const result = [] 59 | const stack = [] 60 | 61 | let last = null 62 | let current = root 63 | 64 | while (current || stack.length > 0) { 65 | while (current) { 66 | stack.push(current) 67 | current = current.left 68 | } 69 | 70 | current = stack[stack.length - 1] 71 | 72 | if (!current.right || current.right === last) { 73 | current = stack.pop() 74 | result.push(current.val) 75 | last = current 76 | current = null 77 | } else { 78 | current = current.right 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /146.lru缓存机制.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=146 lang=javascript 3 | * 4 | * [146] LRU缓存机制 5 | * 6 | * https://leetcode-cn.com/problems/lru-cache/description/ 7 | * 8 | * algorithms 9 | * Medium (43.03%) 10 | * Likes: 240 11 | * Dislikes: 0 12 | * Total Accepted: 17K 13 | * Total Submissions: 39K 14 | * Testcase Example: '["LRUCache","put","put","get","put","get","put","get","get","get"]\n[[2],[1,1],[2,2],[1],[3,3],[2],[4,4],[1],[3],[4]]' 15 | * 16 | * 运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。 17 | * 18 | * 获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。 19 | * 写入数据 put(key, value) - 20 | * 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。 21 | * 22 | * 进阶: 23 | * 24 | * 你是否可以在 O(1) 时间复杂度内完成这两种操作? 25 | * 26 | * 示例: 27 | * 28 | * LRUCache cache = new LRUCache( 2 /* 缓存容量 ); 29 | * 30 | * cache.put(1, 1); 31 | * cache.put(2, 2); 32 | * cache.get(1); // 返回 1 33 | * cache.put(3, 3); // 该操作会使得密钥 2 作废 34 | * cache.get(2); // 返回 -1 (未找到) 35 | * cache.put(4, 4); // 该操作会使得密钥 1 作废 36 | * cache.get(1); // 返回 -1 (未找到) 37 | * cache.get(3); // 返回 3 38 | * cache.get(4); // 返回 4 39 | * 40 | * 41 | */ 42 | 43 | class LRUCache { 44 | constructor(capacity) { 45 | this.capacity = capacity 46 | this.map = new Map() 47 | } 48 | 49 | get(key) { 50 | const val = this.map.get(key) 51 | 52 | if (typeof val === 'undefined') { 53 | return -1 54 | } 55 | 56 | this.map.delete(key) 57 | this.map.set(key, val) 58 | 59 | return val 60 | } 61 | 62 | put(key, value) { 63 | if (this.map.has(key)) { 64 | this.map.delete(key) 65 | } 66 | 67 | this.map.set(key, value) 68 | 69 | const keys = this.map.keys() 70 | 71 | while (this.map.size > this.capacity) { 72 | this.map.delete(keys.next().value) 73 | } 74 | } 75 | } 76 | 77 | /* 78 | * Your LRUCache object will be instantiated and called as such: 79 | * var obj = new LRUCache(capacity) 80 | * var param_1 = obj.get(key) 81 | * obj.put(key,value) 82 | */ 83 | -------------------------------------------------------------------------------- /148.排序链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=148 lang=javascript 3 | * 4 | * [148] 排序链表 5 | * 6 | * https://leetcode-cn.com/problems/sort-list/description/ 7 | * 8 | * algorithms 9 | * Medium (61.79%) 10 | * Likes: 295 11 | * Dislikes: 0 12 | * Total Accepted: 25.5K 13 | * Total Submissions: 41K 14 | * Testcase Example: '[4,2,1,3]' 15 | * 16 | * 在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: 4->2->1->3 21 | * 输出: 1->2->3->4 22 | * 23 | * 24 | * 示例 2: 25 | * 26 | * 输入: -1->5->3->4->0 27 | * 输出: -1->0->3->4->5 28 | * 29 | */ 30 | 31 | // @lc code=start 32 | /** 33 | * Definition for singly-linked list. 34 | * function ListNode(val) { 35 | * this.val = val; 36 | * this.next = null; 37 | * } 38 | */ 39 | /** 40 | * @param {ListNode} head 41 | * @return {ListNode} 42 | */ 43 | const merge = (h1, h2) => { 44 | if (!h1) { 45 | return h2 46 | } 47 | 48 | if (!h2) { 49 | return h1 50 | } 51 | 52 | if (h1.val < h2.val) { 53 | h1.next = merge(h1.next, h2) 54 | return h1 55 | } else { 56 | h2.next = merge(h2.next, h1) 57 | return h2 58 | } 59 | } 60 | 61 | const sortList = head => { 62 | if (!head || !head.next) { 63 | return head 64 | } 65 | 66 | let slow = head 67 | let fast = head 68 | 69 | while (fast && fast.next && fast.next.next) { 70 | slow = slow.next 71 | fast = fast.next.next 72 | } 73 | 74 | fast = slow.next 75 | slow.next = null 76 | 77 | return merge(sortList(head), sortList(fast)) 78 | } 79 | // @lc code=end 80 | -------------------------------------------------------------------------------- /15.三数之和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=15 lang=javascript 3 | * 4 | * [15] 三数之和 5 | * 6 | * https://leetcode-cn.com/problems/3sum/description/ 7 | * 8 | * algorithms 9 | * Medium (23.86%) 10 | * Likes: 1307 11 | * Dislikes: 0 12 | * Total Accepted: 90.3K 13 | * Total Submissions: 378.5K 14 | * Testcase Example: '[-1,0,1,2,-1,-4]' 15 | * 16 | * 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 17 | * ?找出所有满足条件且不重复的三元组。 18 | * 19 | * 注意:答案中不可以包含重复的三元组。 20 | * 21 | * 例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4], 22 | * 23 | * 满足要求的三元组集合为: 24 | * [ 25 | * ⁠ [-1, 0, 1], 26 | * ⁠ [-1, -1, 2] 27 | * ] 28 | * 29 | * 30 | */ 31 | 32 | // @lc code=start 33 | /** 34 | * @param {number[]} nums 35 | * @return {number[][]} 36 | */ 37 | const threeSum = (nums) => { 38 | if (nums.length < 3) { 39 | return [] 40 | } 41 | 42 | const list = [] 43 | 44 | nums.sort((a, b) => a - b) 45 | 46 | for (let i = 0; i < nums.length - 2; i++) { 47 | if (i > 0 && nums[i] === nums[i - 1]) { 48 | continue 49 | } 50 | 51 | let left = i + 1 52 | let right = nums.length - 1 53 | let target = -nums[i] 54 | 55 | while (left < right) { 56 | if (nums[left] + nums[right] === target) { 57 | list.push([nums[i], nums[left], nums[right]]) 58 | 59 | left++ 60 | right-- 61 | 62 | while (left < right && nums[left] === nums[left - 1]) { 63 | left++ 64 | } 65 | 66 | while (left < right && nums[right] === nums[right + 1]) { 67 | right-- 68 | } 69 | } else if (nums[left] + nums[right] < target) { 70 | left++ 71 | } else { 72 | right-- 73 | } 74 | } 75 | } 76 | 77 | return list 78 | } 79 | // @lc code=end 80 | -------------------------------------------------------------------------------- /151.翻转字符串里的单词.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=151 lang=javascript 3 | * 4 | * [151] 翻转字符串里的单词 5 | * 6 | * https://leetcode-cn.com/problems/reverse-words-in-a-string/description/ 7 | * 8 | * algorithms 9 | * Medium (33.28%) 10 | * Likes: 94 11 | * Dislikes: 0 12 | * Total Accepted: 25K 13 | * Total Submissions: 73.9K 14 | * Testcase Example: '"the sky is blue"' 15 | * 16 | * 给定一个字符串,逐个翻转字符串中的每个单词。 17 | * 18 | * 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: "the sky is blue" 23 | * 输出: "blue is sky the" 24 | * 25 | * 26 | * 示例 2: 27 | * 28 | * 输入: "  hello world!  " 29 | * 输出: "world! hello" 30 | * 解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。 31 | * 32 | * 33 | * 示例 3: 34 | * 35 | * 输入: "a good   example" 36 | * 输出: "example good a" 37 | * 解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。 38 | * 39 | * 40 | * 41 | * 42 | * 说明: 43 | * 44 | * 45 | * 无空格字符构成一个单词。 46 | * 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。 47 | * 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。 48 | * 49 | * 50 | * 51 | * 52 | * 进阶: 53 | * 54 | * 请选用 C 语言的用户尝试使用 O(1) 额外空间复杂度的原地解法。 55 | * 56 | */ 57 | 58 | // @lc code=start 59 | /** 60 | * @param {string} s 61 | * @return {string} 62 | */ 63 | const reverseWords = function (s) { 64 | return s 65 | .trim() 66 | .split(' ') 67 | .filter(item => item) 68 | .reverse() 69 | .join(' ') 70 | } 71 | // @lc code=end 72 | -------------------------------------------------------------------------------- /153.寻找旋转排序数组中的最小值.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=153 lang=javascript 3 | * 4 | * [153] 寻找旋转排序数组中的最小值 5 | * 6 | * https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/description/ 7 | * 8 | * algorithms 9 | * Medium (49.96%) 10 | * Likes: 149 11 | * Dislikes: 0 12 | * Total Accepted: 36.2K 13 | * Total Submissions: 72.2K 14 | * Testcase Example: '[3,4,5,1,2]' 15 | * 16 | * 假设按照升序排序的数组在预先未知的某个点上进行了旋转。 17 | * 18 | * ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 19 | * 20 | * 请找出其中最小的元素。 21 | * 22 | * 你可以假设数组中不存在重复元素。 23 | * 24 | * 示例 1: 25 | * 26 | * 输入: [3,4,5,1,2] 27 | * 输出: 1 28 | * 29 | * 示例 2: 30 | * 31 | * 输入: [4,5,6,7,0,1,2] 32 | * 输出: 0 33 | * 34 | */ 35 | 36 | // @lc code=start 37 | /** 38 | * @param {number[]} nums 39 | * @return {number} 40 | */ 41 | const findMin = function (nums) { 42 | // let left = 0 43 | // let right = nums.length - 1 44 | 45 | // while (left < right) { 46 | // let mid = Math.floor(left + ((right - left) >> 1)) 47 | 48 | // if (nums[left] <= nums[mid]) { 49 | // left = mid + 1 50 | // } else { 51 | // right = mid 52 | // } 53 | // } 54 | 55 | // return nums[left] 56 | let l = 0 57 | let r = nums.length - 1 58 | 59 | while (l < r) { 60 | const m = Math.floor((l + r) / 2) 61 | 62 | if (nums[m] > nums[r]) { 63 | l = m + 1 64 | } else { 65 | r = m 66 | } 67 | } 68 | return nums[l] 69 | } 70 | // @lc code=end 71 | -------------------------------------------------------------------------------- /154.寻找旋转排序数组中的最小值-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=154 lang=javascript 3 | * 4 | * [154] 寻找旋转排序数组中的最小值 II 5 | * 6 | * https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/description/ 7 | * 8 | * algorithms 9 | * Hard (45.95%) 10 | * Likes: 85 11 | * Dislikes: 0 12 | * Total Accepted: 16.4K 13 | * Total Submissions: 34.4K 14 | * Testcase Example: '[1,3,5]' 15 | * 16 | * 假设按照升序排序的数组在预先未知的某个点上进行了旋转。 17 | * 18 | * ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 19 | * 20 | * 请找出其中最小的元素。 21 | * 22 | * 注意数组中可能存在重复的元素。 23 | * 24 | * 示例 1: 25 | * 26 | * 输入: [1,3,5] 27 | * 输出: 1 28 | * 29 | * 示例 2: 30 | * 31 | * 输入: [2,2,2,0,1] 32 | * 输出: 0 33 | * 34 | * 说明: 35 | * 36 | * 37 | * 这道题是 寻找旋转排序数组中的最小值 的延伸题目。 38 | * 允许重复会影响算法的时间复杂度吗?会如何影响,为什么? 39 | * 40 | * 41 | */ 42 | 43 | // TODO: 44 | // @lc code=start 45 | /** 46 | * @param {number[]} nums 47 | * @return {number} 48 | */ 49 | var findMin = function (nums) {} 50 | // @lc code=end 51 | -------------------------------------------------------------------------------- /155.最小栈.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=155 lang=javascript 3 | * 4 | * [155] 最小栈 5 | * 6 | * https://leetcode-cn.com/problems/min-stack/description/ 7 | * 8 | * algorithms 9 | * Easy (49.72%) 10 | * Likes: 270 11 | * Dislikes: 0 12 | * Total Accepted: 42.1K 13 | * Total Submissions: 84.4K 14 | * Testcase Example: '["MinStack","push","push","push","getMin","pop","top","getMin"]\n[[],[-2],[0],[-3],[],[],[],[]]' 15 | * 16 | * 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。 17 | * 18 | * 19 | * push(x) -- 将元素 x 推入栈中。 20 | * pop() -- 删除栈顶的元素。 21 | * top() -- 获取栈顶元素。 22 | * getMin() -- 检索栈中的最小元素。 23 | * 24 | * 25 | * 示例: 26 | * 27 | * MinStack minStack = new MinStack(); 28 | * minStack.push(-2); 29 | * minStack.push(0); 30 | * minStack.push(-3); 31 | * minStack.getMin(); --> 返回 -3. 32 | * minStack.pop(); 33 | * minStack.top(); --> 返回 0. 34 | * minStack.getMin(); --> 返回 -2. 35 | * 36 | * 37 | */ 38 | /** 39 | * initialize your data structure here. 40 | */ 41 | const MinStack = function () { 42 | this.minStack = [] 43 | this.container = [] 44 | } 45 | 46 | /** 47 | * @param {number} x 48 | * @return {void} 49 | */ 50 | MinStack.prototype.push = function (x) { 51 | this.container.push(x) 52 | 53 | if ( 54 | this.minStack.length === 0 || 55 | x <= this.minStack[this.minStack.length - 1] 56 | ) { 57 | this.minStack.push(x) 58 | } 59 | } 60 | 61 | /** 62 | * @return {void} 63 | */ 64 | MinStack.prototype.pop = function () { 65 | let x = this.container.pop() 66 | 67 | if (x === this.minStack[this.minStack.length - 1]) { 68 | this.minStack.pop() 69 | } 70 | } 71 | 72 | /** 73 | * @return {number} 74 | */ 75 | MinStack.prototype.top = function () { 76 | return this.container[this.container.length - 1] 77 | } 78 | 79 | /** 80 | * @return {number} 81 | */ 82 | MinStack.prototype.getMin = function () { 83 | return this.minStack[this.minStack.length - 1] 84 | } 85 | 86 | /** 87 | * Your MinStack object will be instantiated and called as such: 88 | * var obj = new MinStack() 89 | * obj.push(x) 90 | * obj.pop() 91 | * var param_3 = obj.top() 92 | * var param_4 = obj.getMin() 93 | */ 94 | -------------------------------------------------------------------------------- /16.最接近的三数之和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=16 lang=javascript 3 | * 4 | * [16] 最接近的三数之和 5 | * 6 | * https://leetcode-cn.com/problems/3sum-closest/description/ 7 | * 8 | * algorithms 9 | * Medium (41.60%) 10 | * Likes: 266 11 | * Dislikes: 0 12 | * Total Accepted: 46.1K 13 | * Total Submissions: 110.6K 14 | * Testcase Example: '[-1,2,1,-4]\n1' 15 | * 16 | * 给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 17 | * 最接近。返回这三个数的和。假定每组输入只存在唯一答案。 18 | * 19 | * 例如,给定数组 nums = [-1,2,1,-4], 和 target = 1. 20 | * 21 | * 与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2). 22 | * 23 | * 24 | */ 25 | 26 | // @lc code=left 27 | /** 28 | * @param {number[]} nums 29 | * @param {number} target 30 | * @return {number} 31 | */ 32 | const threeSumClosest = (nums, target) => { 33 | nums.sort((a, b) => a - b) 34 | 35 | let res = nums[0] + nums[1] + nums[2] 36 | let abs = Math.abs(target - res) 37 | 38 | for (let i = 0; i < nums.length - 2; i++) { 39 | let left = i + 1 40 | let right = nums.length - 1 41 | 42 | while (left < right) { 43 | const sum = nums[i] + nums[left] + nums[right] 44 | const currAbs = Math.abs(target - sum) 45 | 46 | if (currAbs < abs) { 47 | abs = currAbs 48 | res = sum 49 | } 50 | 51 | if (sum > target) { 52 | right-- 53 | } else if (sum < target) { 54 | left++ 55 | } else { 56 | return res 57 | } 58 | } 59 | } 60 | 61 | return res 62 | } // @lc code=end 63 | -------------------------------------------------------------------------------- /160.相交链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=160 lang=javascript 3 | * 4 | * [160] 相交链表 5 | * 6 | * https://leetcode-cn.com/problems/intersection-of-two-linked-lists/description/ 7 | * 8 | * algorithms 9 | * Easy (47.17%) 10 | * Likes: 381 11 | * Dislikes: 0 12 | * Total Accepted: 42K 13 | * Total Submissions: 88.1K 14 | * Testcase Example: '8\n[4,1,8,4,5]\n[5,0,1,8,4,5]\n2\n3' 15 | * 16 | * 编写一个程序,找到两个单链表相交的起始节点。 17 | * 18 | * 如下面的两个链表: 19 | * 20 | * 21 | * 22 | * 在节点 c1 开始相交。 23 | * 24 | * 25 | * 26 | * 示例 1: 27 | * 28 | * 29 | * 30 | * 输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, 31 | * skipB = 3 32 | * 输出:Reference of the node with value = 8 33 | * 输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 34 | * [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。 35 | * 36 | * 37 | * 38 | * 39 | * 示例 2: 40 | * 41 | * 42 | * 43 | * 输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB 44 | * = 1 45 | * 输出:Reference of the node with value = 2 46 | * 输入解释:相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 47 | * [3,2,4]。在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。 48 | * 49 | * 50 | * 51 | * 52 | * 示例 3: 53 | * 54 | * 55 | * 56 | * 输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2 57 | * 输出:null 58 | * 输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersectVal 必须为 59 | * 0,而 skipA 和 skipB 可以是任意值。 60 | * 解释:这两个链表不相交,因此返回 null。 61 | * 62 | * 63 | * 64 | * 65 | * 注意: 66 | * 67 | * 68 | * 如果两个链表没有交点,返回 null. 69 | * 在返回结果后,两个链表仍须保持原有的结构。 70 | * 可假定整个链表结构中没有循环。 71 | * 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。 72 | * 73 | * 74 | */ 75 | /** 76 | * Definition for singly-linked list. 77 | * function ListNode(val) { 78 | * this.val = val; 79 | * this.next = null; 80 | * } 81 | */ 82 | 83 | /** 84 | * @param {ListNode} headA 85 | * @param {ListNode} headB 86 | * @return {ListNode} 87 | */ 88 | const getIntersectionNode = function (headA, headB) { 89 | if (!headA || !headB) { 90 | return null 91 | } 92 | 93 | let currA = headA 94 | let currB = headB 95 | 96 | while (currA !== currB) { 97 | currA = currA === null ? headB : currA.next 98 | currB = currB === null ? headA : currB.next 99 | } 100 | 101 | return currA 102 | } 103 | -------------------------------------------------------------------------------- /162.寻找峰值.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=162 lang=javascript 3 | * 4 | * [162] 寻找峰值 5 | * 6 | * https://leetcode-cn.com/problems/find-peak-element/description/ 7 | * 8 | * algorithms 9 | * Medium (43.17%) 10 | * Likes: 158 11 | * Dislikes: 0 12 | * Total Accepted: 31.9K 13 | * Total Submissions: 70.7K 14 | * Testcase Example: '[1,2,3,1]' 15 | * 16 | * 峰值元素是指其值大于左右相邻值的元素。 17 | * 18 | * 给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。 19 | * 20 | * 数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位置即可。 21 | * 22 | * 你可以假设 nums[-1] = nums[n] = -∞。 23 | * 24 | * 示例 1: 25 | * 26 | * 输入: nums = [1,2,3,1] 27 | * 输出: 2 28 | * 解释: 3 是峰值元素,你的函数应该返回其索引 2。 29 | * 30 | * 示例 2: 31 | * 32 | * 输入: nums = [1,2,1,3,5,6,4] 33 | * 输出: 1 或 5 34 | * 解释: 你的函数可以返回索引 1,其峰值元素为 2; 35 | * 或者返回索引 5, 其峰值元素为 6。 36 | * 37 | * 38 | * 说明: 39 | * 40 | * 你的解法应该是 O(logN) 时间复杂度的。 41 | * 42 | */ 43 | 44 | // @lc code=start 45 | /** 46 | * @param {number[]} nums 47 | * @return {number} 48 | */ 49 | const findPeakElement = function (nums) { 50 | let left = 0 51 | let right = nums.length - 1 52 | 53 | while (left < right) { 54 | let mid = left + ((right - left) >> 1) 55 | 56 | if (nums[mid] > nums[mid + 1]) { 57 | right = mid 58 | } else { 59 | left = mid + 1 60 | } 61 | } 62 | 63 | return left 64 | } 65 | // @lc code=end 66 | -------------------------------------------------------------------------------- /167.两数之和-ii-输入有序数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=167 lang=javascript 3 | * 4 | * [167] 两数之和 II - 输入有序数组 5 | * 6 | * https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/ 7 | * 8 | * algorithms 9 | * Easy (51.17%) 10 | * Likes: 209 11 | * Dislikes: 0 12 | * Total Accepted: 54.1K 13 | * Total Submissions: 105.5K 14 | * Testcase Example: '[2,7,11,15]\n9' 15 | * 16 | * 给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。 17 | * 18 | * 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。 19 | * 20 | * 说明: 21 | * 22 | * 23 | * 返回的下标值(index1 和 index2)不是从零开始的。 24 | * 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。 25 | * 26 | * 27 | * 示例: 28 | * 29 | * 输入: numbers = [2, 7, 11, 15], target = 9 30 | * 输出: [1,2] 31 | * 解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。 32 | * 33 | */ 34 | 35 | // @lc code=start 36 | /** 37 | * @param {number[]} numbers 38 | * @param {number} target 39 | * @return {number[]} 40 | */ 41 | const twoSum = (numbers, target) => { 42 | let left = 0 43 | let right = numbers.length - 1 44 | 45 | while (numbers[left] + numbers[right] !== target) { 46 | if (numbers[left] + numbers[right] > target) { 47 | right-- 48 | } else { 49 | left++ 50 | } 51 | } 52 | 53 | return [left + 1, right + 1] 54 | } 55 | // @lc code=end 56 | -------------------------------------------------------------------------------- /169.多数元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=169 lang=javascript 3 | * 4 | * [169] 多数元素 5 | * 6 | * https://leetcode-cn.com/problems/majority-element/description/ 7 | * 8 | * algorithms 9 | * Easy (60.64%) 10 | * Likes: 373 11 | * Dislikes: 0 12 | * Total Accepted: 88.5K 13 | * Total Submissions: 145.9K 14 | * Testcase Example: '[3,2,3]' 15 | * 16 | * 给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 17 | * 18 | * 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: [3,2,3] 23 | * 输出: 3 24 | * 25 | * 示例 2: 26 | * 27 | * 输入: [2,2,1,1,1,2,2] 28 | * 输出: 2 29 | * 30 | * 31 | */ 32 | 33 | // @lc code=start 34 | /** 35 | * @param {number[]} nums 36 | * @return {number} 37 | */ 38 | const majorityElement = function (nums) { 39 | var obj = {} 40 | 41 | for (var i = 0; i < nums.length; i++) { 42 | obj[nums[i]] = obj[nums[i]] + 1 || 1 43 | 44 | if (obj[nums[i]] > nums.length / 2) { 45 | return nums[i] 46 | } 47 | } 48 | } 49 | // @lc code=end 50 | -------------------------------------------------------------------------------- /169.求众数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=169 lang=javascript 3 | * 4 | * [169] 求众数 5 | * 6 | * https://leetcode-cn.com/problems/majority-element/description/ 7 | * 8 | * algorithms 9 | * Easy (60.29%) 10 | * Likes: 303 11 | * Dislikes: 0 12 | * Total Accepted: 63.8K 13 | * Total Submissions: 105.8K 14 | * Testcase Example: '[3,2,3]' 15 | * 16 | * 给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 17 | * 18 | * 你可以假设数组是非空的,并且给定的数组总是存在众数。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: [3,2,3] 23 | * 输出: 3 24 | * 25 | * 示例 2: 26 | * 27 | * 输入: [2,2,1,1,1,2,2] 28 | * 输出: 2 29 | * 30 | * 31 | */ 32 | /** 33 | * @param {number[]} nums 34 | * @return {number} 35 | */ 36 | const majorityElement = nums => { 37 | let result 38 | const countMap = {} 39 | 40 | nums.forEach(item => { 41 | countMap[item] = countMap[item] + 1 || 1 42 | 43 | if (countMap[item] > nums.length / 2) { 44 | result = item 45 | } 46 | }) 47 | 48 | return result 49 | } 50 | -------------------------------------------------------------------------------- /17.电话号码的字母组合.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=17 lang=javascript 3 | * 4 | * [17] 电话号码的字母组合 5 | * 6 | * https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/description/ 7 | * 8 | * algorithms 9 | * Medium (51.56%) 10 | * Likes: 509 11 | * Dislikes: 0 12 | * Total Accepted: 61.5K 13 | * Total Submissions: 119.3K 14 | * Testcase Example: '"23"' 15 | * 16 | * 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。 17 | * 18 | * 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 19 | * 20 | * 21 | * 22 | * 示例: 23 | * 24 | * 输入:"23" 25 | * 输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. 26 | * 27 | * 28 | * 说明: 29 | * 尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。 30 | * 31 | */ 32 | 33 | //TODO: 34 | // @lc code=start 35 | /** 36 | * @param {string} digits 37 | * @return {string[]} 38 | */ 39 | const letterCombinations = function (digits) { 40 | const map = { 41 | 2: ['a', 'b', 'c'], 42 | 3: ['d', 'e', 'f'], 43 | 4: ['g', 'h', 'i'], 44 | 5: ['j', 'k', 'l'], 45 | 6: ['m', 'n', 'o'], 46 | 7: ['p', 'q', 'r', 's'], 47 | 8: ['t', 'u', 'v'], 48 | 9: ['w', 'x', 'y', 'z'], 49 | } 50 | let result = map[digits[0]] 51 | 52 | digits = digits.substr(1) 53 | digits.split('').forEach(digit => { 54 | let arr = [] 55 | 56 | map[digit].forEach(letter => { 57 | arr = arr.concat(result.map(item => item + letter)) 58 | }) 59 | 60 | result = arr 61 | }) 62 | 63 | return result === undefined ? [] : result 64 | } 65 | // @lc code=end 66 | -------------------------------------------------------------------------------- /171.excel表列序号.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=171 lang=javascript 3 | * 4 | * [171] Excel表列序号 5 | */ 6 | /** 7 | * @param {string} s 8 | * @return {number} 9 | */ 10 | const titleToNumber = s => { 11 | const map = [ 12 | '', 13 | 'A', 14 | 'B', 15 | 'C', 16 | 'D', 17 | 'E', 18 | 'F', 19 | 'G', 20 | 'H', 21 | 'I', 22 | 'J', 23 | 'K', 24 | 'L', 25 | 'M', 26 | 'N', 27 | 'O', 28 | 'P', 29 | 'Q', 30 | 'R', 31 | 'S', 32 | 'T', 33 | 'U', 34 | 'V', 35 | 'W', 36 | 'X', 37 | 'Y', 38 | 'Z', 39 | ] 40 | 41 | let res = 0 42 | let len = s.length 43 | 44 | for (let c of s) { 45 | if (len > 1) { 46 | res += map.indexOf(c) * Math.pow(26, len - 1) 47 | len-- 48 | } else { 49 | res += map.indexOf(c) 50 | } 51 | } 52 | 53 | return res 54 | } 55 | -------------------------------------------------------------------------------- /172.阶乘后的零.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=172 lang=javascript 3 | * 4 | * [172] 阶乘后的零 5 | * 6 | * https://leetcode-cn.com/problems/factorial-trailing-zeroes/description/ 7 | * 8 | * algorithms 9 | * Easy (39.34%) 10 | * Likes: 152 11 | * Dislikes: 0 12 | * Total Accepted: 19.1K 13 | * Total Submissions: 48.5K 14 | * Testcase Example: '3' 15 | * 16 | * 给定一个整数 n,返回 n! 结果尾数中零的数量。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: 3 21 | * 输出: 0 22 | * 解释: 3! = 6, 尾数中没有零。 23 | * 24 | * 示例 2: 25 | * 26 | * 输入: 5 27 | * 输出: 1 28 | * 解释: 5! = 120, 尾数中有 1 个零. 29 | * 30 | * 说明: 你算法的时间复杂度应为 O(log n) 。 31 | * 32 | */ 33 | /** 34 | * @param {number} n 35 | * @return {number} 36 | */ 37 | const trailingZeroes = n => { 38 | let numZeroes = 0 39 | 40 | for (let i = 5; i <= n; i *= 5) { 41 | numZeroes += Math.floor(n / i) 42 | } 43 | 44 | return numZeroes 45 | } 46 | -------------------------------------------------------------------------------- /173.二叉搜索树迭代器.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=173 lang=javascript 3 | * 4 | * [173] 二叉搜索树迭代器 5 | * 6 | * https://leetcode-cn.com/problems/binary-search-tree-iterator/description/ 7 | * 8 | * algorithms 9 | * Medium (72.06%) 10 | * Likes: 150 11 | * Dislikes: 0 12 | * Total Accepted: 16.2K 13 | * Total Submissions: 22.5K 14 | * Testcase Example: '["BSTIterator","next","next","hasNext","next","hasNext","next","hasNext","next","hasNext"]\n[[[7,3,15,null,null,9,20]],[null],[null],[null],[null],[null],[null],[null],[null],[null]]' 15 | * 16 | * 实现一个二叉搜索树迭代器。你将使用二叉搜索树的根节点初始化迭代器。 17 | * 18 | * 调用 next() 将返回二叉搜索树中的下一个最小的数。 19 | * 20 | * 21 | * 22 | * 示例: 23 | * 24 | * 25 | * 26 | * BSTIterator iterator = new BSTIterator(root); 27 | * iterator.next(); // 返回 3 28 | * iterator.next(); // 返回 7 29 | * iterator.hasNext(); // 返回 true 30 | * iterator.next(); // 返回 9 31 | * iterator.hasNext(); // 返回 true 32 | * iterator.next(); // 返回 15 33 | * iterator.hasNext(); // 返回 true 34 | * iterator.next(); // 返回 20 35 | * iterator.hasNext(); // 返回 false 36 | * 37 | * 38 | * 39 | * 提示: 40 | * 41 | * 42 | * next() 和 hasNext() 操作的时间复杂度是 O(1),并使用 O(h) 内存,其中 h 是树的高度。 43 | * 你可以假设 next() 调用总是有效的,也就是说,当调用 next() 时,BST 中至少存在一个下一个最小的数。 44 | * 45 | * 46 | */ 47 | 48 | // @lc code=start 49 | /** 50 | * Definition for a binary tree node. 51 | * function TreeNode(val) { 52 | * this.val = val; 53 | * this.left = this.right = null; 54 | * } 55 | */ 56 | /** 57 | * @param {TreeNode} root 58 | */ 59 | const BSTIterator = function (root) { 60 | this.root = root 61 | this.stack = [] 62 | } 63 | 64 | /** 65 | * @return the next smallest number 66 | * @return {number} 67 | */ 68 | BSTIterator.prototype.next = function () { 69 | while (this.root) { 70 | this.stack.push(this.root) 71 | this.root = this.root.left 72 | } 73 | 74 | this.root = this.stack.pop() 75 | let result = this.root.val 76 | this.root = this.root.right 77 | return result 78 | } 79 | 80 | /** 81 | * @return whether we have a next smallest number 82 | * @return {boolean} 83 | */ 84 | BSTIterator.prototype.hasNext = function () { 85 | return this.root || this.stack.length 86 | } 87 | 88 | /** 89 | * Your BSTIterator object will be instantiated and called as such: 90 | * var obj = new BSTIterator(root) 91 | * var param_1 = obj.next() 92 | * var param_2 = obj.hasNext() 93 | */ 94 | // @lc code=end 95 | -------------------------------------------------------------------------------- /189.旋转数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=189 lang=javascript 3 | * 4 | * [189] 旋转数组 5 | * 6 | * https://leetcode-cn.com/problems/rotate-array/description/ 7 | * 8 | * algorithms 9 | * Easy (38.49%) 10 | * Likes: 369 11 | * Dislikes: 0 12 | * Total Accepted: 66.7K 13 | * Total Submissions: 172.5K 14 | * Testcase Example: '[1,2,3,4,5,6,7]\n3' 15 | * 16 | * 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: [1,2,3,4,5,6,7] 和 k = 3 21 | * 输出: [5,6,7,1,2,3,4] 22 | * 解释: 23 | * 向右旋转 1 步: [7,1,2,3,4,5,6] 24 | * 向右旋转 2 步: [6,7,1,2,3,4,5] 25 | * 向右旋转 3 步: [5,6,7,1,2,3,4] 26 | * 27 | * 28 | * 示例 2: 29 | * 30 | * 输入: [-1,-100,3,99] 和 k = 2 31 | * 输出: [3,99,-1,-100] 32 | * 解释: 33 | * 向右旋转 1 步: [99,-1,-100,3] 34 | * 向右旋转 2 步: [3,99,-1,-100] 35 | * 36 | * 说明: 37 | * 38 | * 39 | * 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。 40 | * 要求使用空间复杂度为 O(1) 的 原地 算法。 41 | * 42 | * 43 | */ 44 | /** 45 | * @param {number[]} nums 46 | * @param {number} k 47 | * @return {void} Do not return anything, modify nums in-place instead. 48 | */ 49 | const rotate = (nums, k) => { 50 | let temp 51 | let prev 52 | 53 | for (let i = 0; i < k; i++) { 54 | prev = nums[nums.length - 1] 55 | 56 | for (let j = 0; j < nums.length; j++) { 57 | temp = nums[j] 58 | nums[j] = prev 59 | prev = temp 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /19.remove-nth-node-from-end-of-list.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=19 lang=javascript 3 | * 4 | * [19] Remove Nth Node From End of List 5 | */ 6 | /** 7 | * Definition for singly-linked list. 8 | * function ListNode(val) { 9 | * this.val = val; 10 | * this.next = null; 11 | * } 12 | */ 13 | /** 14 | * @param {ListNode} head 15 | * @param {number} n 16 | * @return {ListNode} 17 | */ 18 | // https://pic.leetcode-cn.com/cc43daa8cbb755373ce4c5cd10c44066dc770a34a6d2913a52f8047cbf5e6e56-file_1559548337458 19 | const removeNthFromEnd = (head, n) => { 20 | let pre = { next: head } 21 | let start = pre 22 | let end = pre 23 | 24 | n = n + 1 25 | 26 | while (n--) { 27 | start = start.next 28 | } 29 | 30 | while (start) { 31 | start = start.next 32 | end = end.next 33 | } 34 | 35 | end.next = end.next.next 36 | 37 | return pre.next 38 | } 39 | -------------------------------------------------------------------------------- /19.删除链表的倒数第n个节点.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=19 lang=javascript 3 | * 4 | * [19] 删除链表的倒数第N个节点 5 | * 6 | * https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/description/ 7 | * 8 | * algorithms 9 | * Medium (36.20%) 10 | * Likes: 604 11 | * Dislikes: 0 12 | * Total Accepted: 96.1K 13 | * Total Submissions: 263.3K 14 | * Testcase Example: '[1,2,3,4,5]\n2' 15 | * 16 | * 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。 17 | * 18 | * 示例: 19 | * 20 | * 给定一个链表: 1->2->3->4->5, 和 n = 2. 21 | * 22 | * 当删除了倒数第二个节点后,链表变为 1->2->3->5. 23 | * 24 | * 25 | * 说明: 26 | * 27 | * 给定的 n 保证是有效的。 28 | * 29 | * 进阶: 30 | * 31 | * 你能尝试使用一趟扫描实现吗? 32 | * 33 | */ 34 | 35 | // @lc code=start 36 | /** 37 | * Definition for singly-linked list. 38 | * function ListNode(val) { 39 | * this.val = val; 40 | * this.next = null; 41 | * } 42 | */ 43 | /** 44 | * @param {ListNode} head 45 | * @param {number} n 46 | * @return {ListNode} 47 | */ 48 | const removeNthFromEnd = function (head, n) { 49 | const pre = new ListNode(0) 50 | 51 | pre.next = head 52 | 53 | let slow = pre 54 | let fast = pre 55 | 56 | while (n !== 0) { 57 | fast = fast.next 58 | n-- 59 | } 60 | 61 | while (fast.next !== null) { 62 | fast = fast.next 63 | slow = slow.next 64 | } 65 | 66 | slow.next = slow.next.next 67 | 68 | return pre.next 69 | } 70 | // @lc code=end 71 | -------------------------------------------------------------------------------- /190.颠倒二进制位.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=190 lang=javascript 3 | * 4 | * [190] 颠倒二进制位 5 | * 6 | * https://leetcode-cn.com/problems/reverse-bits/description/ 7 | * 8 | * algorithms 9 | * Easy (46.47%) 10 | * Likes: 91 11 | * Dislikes: 0 12 | * Total Accepted: 20.4K 13 | * Total Submissions: 42.1K 14 | * Testcase Example: '00000010100101000001111010011100' 15 | * 16 | * 颠倒给定的 32 位无符号整数的二进制位。 17 | * 18 | * 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: 00000010100101000001111010011100 23 | * 输出: 00111001011110000010100101000000 24 | * 解释: 输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596, 25 | * ⁠ 因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。 26 | * 27 | * 示例 2: 28 | * 29 | * 输入:11111111111111111111111111111101 30 | * 输出:10111111111111111111111111111111 31 | * 解释:输入的二进制串 11111111111111111111111111111101 表示无符号整数 4294967293, 32 | * 因此返回 3221225471 其二进制表示形式为 10101111110010110010011101101001。 33 | * 34 | * 35 | * 36 | * 提示: 37 | * 38 | * 39 | * 请注意,在某些语言(如 40 | * Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。 41 | * 在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 2 中,输入表示有符号整数 -3,输出表示有符号整数 42 | * -1073741825。 43 | * 44 | * 45 | * 46 | * 47 | * 进阶: 48 | * 如果多次调用这个函数,你将如何优化你的算法? 49 | * 50 | */ 51 | /** 52 | * @param {number} n - a positive integer 53 | * @return {number} - a positive integer 54 | */ 55 | 56 | // TODO: 57 | var reverseBits = function (n) { 58 | var result = 0 59 | var count = 32 60 | 61 | while (count--) { 62 | result *= 2 63 | result += n & 1 64 | n = n >> 1 65 | } 66 | 67 | return result 68 | } 69 | -------------------------------------------------------------------------------- /191.位-1-的个数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=191 lang=javascript 3 | * 4 | * [191] 位1的个数 5 | * 6 | * https://leetcode-cn.com/problems/number-of-1-bits/description/ 7 | * 8 | * algorithms 9 | * Easy (57.75%) 10 | * Likes: 97 11 | * Dislikes: 0 12 | * Total Accepted: 30.4K 13 | * Total Submissions: 51.4K 14 | * Testcase Example: '00000000000000000000000000001011' 15 | * 16 | * 编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。 17 | * 18 | * 19 | * 20 | * 示例 1: 21 | * 22 | * 输入:00000000000000000000000000001011 23 | * 输出:3 24 | * 解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。 25 | * 26 | * 27 | * 示例 2: 28 | * 29 | * 输入:00000000000000000000000010000000 30 | * 输出:1 31 | * 解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。 32 | * 33 | * 34 | * 示例 3: 35 | * 36 | * 输入:11111111111111111111111111111101 37 | * 输出:31 38 | * 解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。 39 | * 40 | * 41 | * 42 | * 提示: 43 | * 44 | * 45 | * 请注意,在某些语言(如 46 | * Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。 47 | * 在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 3 中,输入表示有符号整数 -3。 48 | * 49 | * 50 | * 51 | * 52 | * 进阶: 53 | * 如果多次调用这个函数,你将如何优化你的算法? 54 | * 55 | */ 56 | /** 57 | * @param {number} n - a positive integer 58 | * @return {number} 59 | */ 60 | var hammingWeight = function (n) { 61 | return n.toString(2).replace(/0/g, '').length 62 | } 63 | -------------------------------------------------------------------------------- /198.打家劫舍.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=198 lang=javascript 3 | * 4 | * [198] 打家劫舍 5 | * 6 | * https://leetcode-cn.com/problems/house-robber/description/ 7 | * 8 | * algorithms 9 | * Easy (41.25%) 10 | * Likes: 479 11 | * Dislikes: 0 12 | * Total Accepted: 47K 13 | * Total Submissions: 112.5K 14 | * Testcase Example: '[1,2,3,1]' 15 | * 16 | * 17 | * 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 18 | * 19 | * 给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。 20 | * 21 | * 示例 1: 22 | * 23 | * 输入: [1,2,3,1] 24 | * 输出: 4 25 | * 解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。 26 | * 偷窃到的最高金额 = 1 + 3 = 4 。 27 | * 28 | * 示例 2: 29 | * 30 | * 输入: [2,7,9,3,1] 31 | * 输出: 12 32 | * 解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。 33 | * 偷窃到的最高金额 = 2 + 9 + 1 = 12 。 34 | * 35 | * 36 | */ 37 | /** 38 | * @param {number[]} nums 39 | * @return {number} 40 | */ 41 | const rob = nums => { 42 | const len = nums.length 43 | 44 | if (len === 0) { 45 | return 0 46 | } 47 | 48 | const dp = [] 49 | 50 | dp[0] = 0 51 | dp[1] = nums[0] 52 | 53 | for (let i = 2; i <= len; i++) { 54 | dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i - 1]) 55 | } 56 | 57 | return dp[len] 58 | } 59 | -------------------------------------------------------------------------------- /2.add-two-numbers.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=2 lang=javascript 3 | * 4 | * [2] Add Two Numbers 5 | */ 6 | /** 7 | * Definition for singly-linked list. 8 | * function ListNode(val) { 9 | * this.val = val; 10 | * this.next = null; 11 | * } 12 | */ 13 | /** 14 | * @param {ListNode} l1 15 | * @param {ListNode} l2 16 | * @return {ListNode} 17 | */ 18 | var addTwoNumbers = function (l1, l2) { 19 | var List = new ListNode(0) 20 | var head = List 21 | var sum = 0 22 | var carry = 0 23 | 24 | while (l1 !== null || l2 !== null || sum > 0) { 25 | if (l1 !== null) { 26 | sum = sum + l1.val 27 | l1 = l1.next 28 | } 29 | if (l2 !== null) { 30 | sum = sum + l2.val 31 | l2 = l2.next 32 | } 33 | if (sum >= 10) { 34 | carry = 1 35 | sum = sum - 10 36 | } 37 | 38 | head.next = new ListNode(sum) 39 | head = head.next 40 | 41 | sum = carry 42 | carry = 0 43 | } 44 | 45 | return List.next 46 | } 47 | -------------------------------------------------------------------------------- /2.两数相加.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=2 lang=javascript 3 | * 4 | * [2] 两数相加 5 | * 6 | * https://leetcode-cn.com/problems/add-two-numbers/description/ 7 | * 8 | * algorithms 9 | * Medium (35.36%) 10 | * Likes: 2985 11 | * Dislikes: 0 12 | * Total Accepted: 199.6K 13 | * Total Submissions: 561.5K 14 | * Testcase Example: '[2,4,3]\n[5,6,4]' 15 | * 16 | * 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。 17 | * 18 | * 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。 19 | * 20 | * 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。 21 | * 22 | * 示例: 23 | * 24 | * 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 25 | * 输出:7 -> 0 -> 8 26 | * 原因:342 + 465 = 807 27 | * 28 | * 29 | */ 30 | /** 31 | * Definition for singly-linked list. 32 | * function ListNode(val) { 33 | * this.val = val; 34 | * this.next = null; 35 | * } 36 | */ 37 | /** 38 | * @param {ListNode} l1 39 | * @param {ListNode} l2 40 | * @return {ListNode} 41 | */ 42 | const addTwoNumbers = (l1, l2) => { 43 | let pre = new ListNode(0) 44 | let head = pre 45 | 46 | let sum = 0 47 | let carry = 0 48 | 49 | while (l1 !== null || l2 !== null || sum > 0) { 50 | if (l1 !== null) { 51 | sum += l1.val 52 | l1 = l1.next 53 | } 54 | 55 | if (l2 !== null) { 56 | sum += l2.val 57 | l2 = l2.next 58 | } 59 | 60 | if (sum >= 10) { 61 | carry = 1 62 | sum = sum - 10 63 | } 64 | 65 | head.next = new ListNode(sum) 66 | head = head.next 67 | 68 | sum = carry 69 | carry = 0 70 | } 71 | 72 | return pre.next 73 | } 74 | -------------------------------------------------------------------------------- /20.有效的括号.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=20 lang=javascript 3 | * 4 | * [20] 有效的括号 5 | * 6 | * https://leetcode-cn.com/problems/valid-parentheses/description/ 7 | * 8 | * algorithms 9 | * Easy (39.32%) 10 | * Likes: 1034 11 | * Dislikes: 0 12 | * Total Accepted: 118.4K 13 | * Total Submissions: 299.6K 14 | * Testcase Example: '"()"' 15 | * 16 | * 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。 17 | * 18 | * 有效字符串需满足: 19 | * 20 | * 21 | * 左括号必须用相同类型的右括号闭合。 22 | * 左括号必须以正确的顺序闭合。 23 | * 24 | * 25 | * 注意空字符串可被认为是有效字符串。 26 | * 27 | * 示例 1: 28 | * 29 | * 输入: "()" 30 | * 输出: true 31 | * 32 | * 33 | * 示例 2: 34 | * 35 | * 输入: "()[]{}" 36 | * 输出: true 37 | * 38 | * 39 | * 示例 3: 40 | * 41 | * 输入: "(]" 42 | * 输出: false 43 | * 44 | * 45 | * 示例 4: 46 | * 47 | * 输入: "([)]" 48 | * 输出: false 49 | * 50 | * 51 | * 示例 5: 52 | * 53 | * 输入: "{[]}" 54 | * 输出: true 55 | * 56 | */ 57 | /** 58 | * @param {string} s 59 | * @return {boolean} 60 | */ 61 | const isValid = s => { 62 | const map = { 63 | '(': ')', 64 | '[': ']', 65 | '{': '}', 66 | } 67 | const stack = [] 68 | 69 | for (let str of s) { 70 | if (str in map) { 71 | stack.push(str) 72 | } else { 73 | const curr = map[stack.pop()] 74 | 75 | if (str !== curr) { 76 | return false 77 | } 78 | } 79 | } 80 | 81 | return !stack.length 82 | } 83 | -------------------------------------------------------------------------------- /200.岛屿数量.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=200 lang=javascript 3 | * 4 | * [200] 岛屿数量 5 | * 6 | * https://leetcode-cn.com/problems/number-of-islands/description/ 7 | * 8 | * algorithms 9 | * Medium (46.14%) 10 | * Likes: 310 11 | * Dislikes: 0 12 | * Total Accepted: 44.4K 13 | * Total Submissions: 96K 14 | * Testcase Example: '[["1","1","1","1","0"],["1","1","0","1","0"],["1","1","0","0","0"],["0","0","0","0","0"]]' 15 | * 16 | * 给定一个由 '1'(陆地)和 17 | * '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。 18 | * 19 | * 示例 1: 20 | * 21 | * 输入: 22 | * 11110 23 | * 11010 24 | * 11000 25 | * 00000 26 | * 27 | * 输出: 1 28 | * 29 | * 30 | * 示例 2: 31 | * 32 | * 输入: 33 | * 11000 34 | * 11000 35 | * 00100 36 | * 00011 37 | * 38 | * 输出: 3 39 | * 40 | * 41 | */ 42 | 43 | // @lc code=start 44 | /** 45 | * @param {character[][]} grid 46 | * @return {number} 47 | */ 48 | var numIslands = function (grid) {} 49 | // @lc code=end 50 | -------------------------------------------------------------------------------- /202.快乐数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=202 lang=javascript 3 | * 4 | * [202] 快乐数 5 | * 6 | * https://leetcode-cn.com/problems/happy-number/description/ 7 | * 8 | * algorithms 9 | * Easy (54.69%) 10 | * Likes: 166 11 | * Dislikes: 0 12 | * Total Accepted: 29.6K 13 | * Total Submissions: 53.7K 14 | * Testcase Example: '19' 15 | * 16 | * 编写一个算法来判断一个数是不是“快乐数”。 17 | * 18 | * 一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 19 | * 1。如果可以变为 1,那么这个数就是快乐数。 20 | * 21 | * 示例: 22 | * 23 | * 输入: 19 24 | * 输出: true 25 | * 解释: 26 | * 1^2 + 9^2 = 82 27 | * 8^2 + 2^2 = 68 28 | * 6^2 + 8^2 = 100 29 | * 1^2 + 0^2 + 0^2 = 1 30 | * 31 | * 32 | */ 33 | /** 34 | * @param {number} n 35 | * @return {boolean} 36 | */ 37 | const isHappy = n => { 38 | let set = new Set() 39 | let sum = 0 40 | 41 | n += '' 42 | 43 | while (sum !== 1) { 44 | sum = 0 45 | 46 | for (let i = 0; i < n.length; i++) { 47 | sum += n[i] * n[i] 48 | } 49 | 50 | n = sum + '' 51 | 52 | if (set.has(sum)) { 53 | return false 54 | } 55 | 56 | set.add(sum) 57 | } 58 | 59 | return true 60 | } 61 | -------------------------------------------------------------------------------- /203.移除链表元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=203 lang=javascript 3 | * 4 | * [203] 移除链表元素 5 | * 6 | * https://leetcode-cn.com/problems/remove-linked-list-elements/description/ 7 | * 8 | * algorithms 9 | * Easy (42.75%) 10 | * Likes: 312 11 | * Dislikes: 0 12 | * Total Accepted: 48K 13 | * Total Submissions: 111.6K 14 | * Testcase Example: '[1,2,6,3,4,5,6]\n6' 15 | * 16 | * 删除链表中等于给定值 val 的所有节点。 17 | * 18 | * 示例: 19 | * 20 | * 输入: 1->2->6->3->4->5->6, val = 6 21 | * 输出: 1->2->3->4->5 22 | * 23 | * 24 | */ 25 | 26 | // @lc code=start 27 | /** 28 | * Definition for singly-linked list. 29 | * function ListNode(val) { 30 | * this.val = val; 31 | * this.next = null; 32 | * } 33 | */ 34 | /** 35 | * @param {ListNode} head 36 | * @param {number} val 37 | * @return {ListNode} 38 | */ 39 | const removeElements = function (head, val) { 40 | if (!head) { 41 | return head 42 | } 43 | 44 | while (head) { 45 | if (head.val === val) { 46 | head = head.next 47 | } else { 48 | break 49 | } 50 | } 51 | 52 | let curr = head 53 | 54 | while (curr && curr.next) { 55 | if (curr.next.val === val) { 56 | curr.next = curr.next.next 57 | } else { 58 | curr = curr.next 59 | } 60 | } 61 | 62 | return head 63 | } 64 | // @lc code=end 65 | -------------------------------------------------------------------------------- /204.计数质数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=204 lang=javascript 3 | * 4 | * [204] 计数质数 5 | * 6 | * https://leetcode-cn.com/problems/count-primes/description/ 7 | * 8 | * algorithms 9 | * Easy (29.64%) 10 | * Likes: 198 11 | * Dislikes: 0 12 | * Total Accepted: 27.5K 13 | * Total Submissions: 91.4K 14 | * Testcase Example: '10' 15 | * 16 | * 统计所有小于非负整数 n 的质数的数量。 17 | * 18 | * 示例: 19 | * 20 | * 输入: 10 21 | * 输出: 4 22 | * 解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。 23 | * 24 | * 25 | */ 26 | /** 27 | * @param {number} n 28 | * @return {number} 29 | */ 30 | //TODO: 31 | const countPrimes = function (n) { 32 | let count = 0 33 | let signs = [] 34 | 35 | for (let i = 2; i < n; i++) { 36 | if (!signs[i]) { 37 | count++ 38 | for (let j = 2 * i; j < n; j += i) { 39 | signs[j] = true 40 | } 41 | } 42 | } 43 | 44 | return count 45 | } 46 | -------------------------------------------------------------------------------- /206.reverse-linked-list.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=206 lang=javascript 3 | * 4 | * [206] Reverse Linked List 5 | */ 6 | /** 7 | * Definition for singly-linked list. 8 | * function ListNode(val) { 9 | * this.val = val; 10 | * this.next = null; 11 | * } 12 | */ 13 | /** 14 | * @param {ListNode} head 15 | * @return {ListNode} 16 | */ 17 | const reverseList = head => { 18 | let temp = null 19 | let newHead = null 20 | 21 | while (head !== null) { 22 | temp = head 23 | head = head.next 24 | 25 | temp.next = newHead 26 | newHead = temp 27 | } 28 | 29 | return newHead 30 | } 31 | -------------------------------------------------------------------------------- /206.反转链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=206 lang=javascript 3 | * 4 | * [206] 反转链表 5 | * 6 | * https://leetcode-cn.com/problems/reverse-linked-list/description/ 7 | * 8 | * algorithms 9 | * Easy (63.82%) 10 | * Likes: 552 11 | * Dislikes: 0 12 | * Total Accepted: 91.4K 13 | * Total Submissions: 142.6K 14 | * Testcase Example: '[1,2,3,4,5]' 15 | * 16 | * 反转一个单链表。 17 | * 18 | * 示例: 19 | * 20 | * 输入: 1->2->3->4->5->NULL 21 | * 输出: 5->4->3->2->1->NULL 22 | * 23 | * 进阶: 24 | * 你可以迭代或递归地反转链表。你能否用两种方法解决这道题? 25 | * 26 | */ 27 | /** 28 | * Definition for singly-linked list. 29 | * function ListNode(val) { 30 | * this.val = val; 31 | * this.next = null; 32 | * } 33 | */ 34 | /** 35 | * @param {ListNode} head 36 | * @return {ListNode} 37 | */ 38 | const reverseList = head => { 39 | if (head === null) { 40 | return null 41 | } 42 | 43 | let pre = null 44 | let next = null 45 | 46 | while (head !== null) { 47 | next = head.next 48 | head.next = pre 49 | pre = head 50 | head = next 51 | } 52 | 53 | return pre 54 | } 55 | -------------------------------------------------------------------------------- /209.长度最小的子数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=209 lang=javascript 3 | * 4 | * [209] 长度最小的子数组 5 | * 6 | * https://leetcode-cn.com/problems/minimum-size-subarray-sum/description/ 7 | * 8 | * algorithms 9 | * Medium (40.28%) 10 | * Likes: 154 11 | * Dislikes: 0 12 | * Total Accepted: 21.5K 13 | * Total Submissions: 53.3K 14 | * Testcase Example: '7\n[2,3,1,2,4,3]' 15 | * 16 | * 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。 17 | * 18 | * 示例: 19 | * 20 | * 输入: s = 7, nums = [2,3,1,2,4,3] 21 | * 输出: 2 22 | * 解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。 23 | * 24 | * 25 | * 进阶: 26 | * 27 | * 如果你已经完成了O(n) 时间复杂度的解法, 请尝试 O(n log n) 时间复杂度的解法。 28 | * 29 | */ 30 | 31 | // @lc code=start 32 | /** 33 | * @param {number} s 34 | * @param {number[]} nums 35 | * @return {number} 36 | */ 37 | const minSubArrayLen = function (s, nums) { 38 | let min = Infinity 39 | let left = 0 40 | let sum = 0 41 | 42 | for (let i = 0; i < nums.length; i++) { 43 | sum += nums[i] 44 | while (sum >= s) { 45 | min = Math.min(min, i + 1 - left) 46 | sum -= nums[left++] 47 | } 48 | } 49 | 50 | return min === Infinity ? 0 : min 51 | } 52 | // @lc code=end 53 | -------------------------------------------------------------------------------- /21.merge-two-sorted-lists.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=21 lang=javascript 3 | * 4 | * [21] Merge Two Sorted Lists 5 | */ 6 | /** 7 | * Definition for singly-linked list. 8 | * function ListNode(val) { 9 | * this.val = val; 10 | * this.next = null; 11 | * } 12 | */ 13 | /** 14 | * @param {ListNode} l1 15 | * @param {ListNode} l2 16 | * @return {ListNode} 17 | */ 18 | const mergeTwoLists = (l1, l2) => { 19 | if (!l1 || !l2) { 20 | return l1 || l2 21 | } 22 | 23 | if (l1.val < l2.val) { 24 | l1.next = mergeTwoLists(l1.next, l2) 25 | return l1 26 | } 27 | l2.next = mergeTwoLists(l1, l2.next) 28 | 29 | return l2 30 | } 31 | -------------------------------------------------------------------------------- /21.合并两个有序链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=21 lang=javascript 3 | * 4 | * [21] 合并两个有序链表 5 | * 6 | * https://leetcode-cn.com/problems/merge-two-sorted-lists/description/ 7 | * 8 | * algorithms 9 | * Easy (56.66%) 10 | * Likes: 603 11 | * Dislikes: 0 12 | * Total Accepted: 104.8K 13 | * Total Submissions: 184.1K 14 | * Testcase Example: '[1,2,4]\n[1,3,4]' 15 | * 16 | * 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 17 | * 18 | * 示例: 19 | * 20 | * 输入:1->2->4, 1->3->4 21 | * 输出:1->1->2->3->4->4 22 | * 23 | * 24 | */ 25 | /** 26 | * Definition for singly-linked list. 27 | * function ListNode(val) { 28 | * this.val = val; 29 | * this.next = null; 30 | * } 31 | */ 32 | /** 33 | * @param {ListNode} l1 34 | * @param {ListNode} l2 35 | * @return {ListNode} 36 | */ 37 | const mergeTwoLists = (l1, l2) => { 38 | if (l1 === null) { 39 | return l2 40 | } 41 | 42 | if (l2 === null) { 43 | return l1 44 | } 45 | 46 | if (l1.val < l2.val) { 47 | l1.next = mergeTwoLists(l1.next, l2) 48 | return l1 49 | } else { 50 | l2.next = mergeTwoLists(l2.next, l1) 51 | return l2 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /215.数组中的第k个最大元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=215 lang=javascript 3 | * 4 | * [215] 数组中的第K个最大元素 5 | * 6 | * https://leetcode-cn.com/problems/kth-largest-element-in-an-array/description/ 7 | * 8 | * algorithms 9 | * Medium (58.16%) 10 | * Likes: 268 11 | * Dislikes: 0 12 | * Total Accepted: 48.8K 13 | * Total Submissions: 83.4K 14 | * Testcase Example: '[3,2,1,5,6,4]\n2' 15 | * 16 | * 在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: [3,2,1,5,6,4] 和 k = 2 21 | * 输出: 5 22 | * 23 | * 24 | * 示例 2: 25 | * 26 | * 输入: [3,2,3,1,2,4,5,5,6] 和 k = 4 27 | * 输出: 4 28 | * 29 | * 说明: 30 | * 31 | * 你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。 32 | * 33 | */ 34 | 35 | // @lc code=start 36 | /** 37 | * @param {number[]} nums 38 | * @param {number} k 39 | * @return {number} 40 | */ 41 | const findKthLargest = (nums, k) => { 42 | nums.sort((a, b) => b - a) 43 | return nums[k - 1] 44 | } 45 | // @lc code=end 46 | -------------------------------------------------------------------------------- /217.存在重复元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=217 lang=javascript 3 | * 4 | * [217] 存在重复元素 5 | * 6 | * https://leetcode-cn.com/problems/contains-duplicate/description/ 7 | * 8 | * algorithms 9 | * Easy (49.69%) 10 | * Likes: 164 11 | * Dislikes: 0 12 | * Total Accepted: 73.6K 13 | * Total Submissions: 147.9K 14 | * Testcase Example: '[1,2,3,1]' 15 | * 16 | * 给定一个整数数组,判断是否存在重复元素。 17 | * 18 | * 如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: [1,2,3,1] 23 | * 输出: true 24 | * 25 | * 示例 2: 26 | * 27 | * 输入: [1,2,3,4] 28 | * 输出: false 29 | * 30 | * 示例 3: 31 | * 32 | * 输入: [1,1,1,3,3,4,3,2,4,2] 33 | * 输出: true 34 | * 35 | */ 36 | /** 37 | * @param {number[]} nums 38 | * @return {boolean} 39 | */ 40 | const containsDuplicate = nums => { 41 | const map = {} 42 | 43 | for (let item of nums) { 44 | if (!(item in map)) { 45 | map[item] = true 46 | } else { 47 | return true 48 | } 49 | } 50 | 51 | return false 52 | } 53 | -------------------------------------------------------------------------------- /22.括号生成.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=22 lang=javascript 3 | * 4 | * [22] 括号生成 5 | */ 6 | /** 7 | * @param {number} n 8 | * @return {string[]} 9 | */ 10 | const generateParenthesis = n => { 11 | const res = [] 12 | const fn = (str, l, r) => { 13 | if (l === n && r === n) { 14 | res.push(str) 15 | return 16 | } 17 | 18 | if (l < n) { 19 | fn(`${str}(`, l + 1, r) 20 | } 21 | 22 | if (l > r) { 23 | fn(`${str})`, l, r + 1) 24 | } 25 | } 26 | 27 | fn('', 0, 0) 28 | 29 | return res 30 | } 31 | -------------------------------------------------------------------------------- /220.存在重复元素-iii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=220 lang=javascript 3 | * 4 | * [220] 存在重复元素 III 5 | * 6 | * https://leetcode-cn.com/problems/contains-duplicate-iii/description/ 7 | * 8 | * algorithms 9 | * Medium (25.86%) 10 | * Likes: 158 11 | * Dislikes: 0 12 | * Total Accepted: 15.2K 13 | * Total Submissions: 58.7K 14 | * Testcase Example: '[1,2,3,1]\n3\n0' 15 | * 16 | * 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 17 | * 之间的差的绝对值最大为 ķ。 18 | * 19 | * 示例 1: 20 | * 21 | * 输入: nums = [1,2,3,1], k = 3, t = 0 22 | * 输出: true 23 | * 24 | * 示例 2: 25 | * 26 | * 输入: nums = [1,0,1,1], k = 1, t = 2 27 | * 输出: true 28 | * 29 | * 示例 3: 30 | * 31 | * 输入: nums = [1,5,9,1,5,9], k = 2, t = 3 32 | * 输出: false 33 | * 34 | */ 35 | 36 | // TODO: 37 | // @lc code=start 38 | /** 39 | * @param {number[]} nums 40 | * @param {number} k 41 | * @param {number} t 42 | * @return {boolean} 43 | */ 44 | var containsNearbyAlmostDuplicate = function (nums, k, t) {} 45 | // @lc code=end 46 | -------------------------------------------------------------------------------- /225.用队列实现栈.js: -------------------------------------------------------------------------------- 1 | var MyStack = function() { 2 | this.data = [] 3 | } 4 | 5 | MyStack.prototype.push = function(x) { 6 | this.data.push(x) 7 | } 8 | MyStack.prototype.pop = function() { 9 | return this.data.splice(this.data.length - 1, 1) 10 | } 11 | 12 | MyStack.prototype.top = function() { 13 | return this.data[this.data.length - 1] 14 | } 15 | 16 | MyStack.prototype.empty = function() { 17 | return this.data.length === 0 18 | } 19 | -------------------------------------------------------------------------------- /23.合并k个排序链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=23 lang=javascript 3 | * 4 | * [23] 合并K个排序链表 5 | * 6 | * https://leetcode-cn.com/problems/merge-k-sorted-lists/description/ 7 | * 8 | * algorithms 9 | * Hard (47.38%) 10 | * Likes: 349 11 | * Dislikes: 0 12 | * Total Accepted: 46K 13 | * Total Submissions: 96.7K 14 | * Testcase Example: '[[1,4,5],[1,3,4],[2,6]]' 15 | * 16 | * 合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 17 | * 18 | * 示例: 19 | * 20 | * 输入: 21 | * [ 22 | * 1->4->5, 23 | * 1->3->4, 24 | * 2->6 25 | * ] 26 | * 输出: 1->1->2->3->4->4->5->6 27 | * 28 | */ 29 | 30 | // @lc code=start 31 | /** 32 | * Definition for singly-linked list. 33 | * function ListNode(val) { 34 | * this.val = val; 35 | * this.next = null; 36 | * } 37 | */ 38 | /** 39 | * @param {ListNode[]} lists 40 | * @return {ListNode} 41 | */ 42 | 43 | const mergeTwoLists = (l1, l2) => { 44 | if (l1 === null) { 45 | return l2 46 | } 47 | 48 | if (l2 === null) { 49 | return l1 50 | } 51 | 52 | if (l1.val < l2.val) { 53 | l1.next = mergeTwoLists(l1.next, l2) 54 | return l1 55 | } else { 56 | l2.next = mergeTwoLists(l2.next, l1) 57 | return l2 58 | } 59 | } 60 | 61 | const mergeKLists = function (lists) { 62 | if (lists.length === 0) { 63 | return null 64 | } 65 | 66 | if (lists.length === 1) { 67 | return lists[0] 68 | } 69 | 70 | if (lists.length === 2) { 71 | return mergeTwoLists(lists[0], lists[1]) 72 | } 73 | 74 | const left = [] 75 | const right = [] 76 | const mid = Math.floor(lists.length / 2) 77 | 78 | for (let i = 0; i < lists.length; i++) { 79 | if (i < mid) { 80 | left.push(lists[i]) 81 | } else { 82 | right.push(lists[i]) 83 | } 84 | } 85 | 86 | return mergeTwoLists(mergeKLists(left), mergeKLists(right)) 87 | } 88 | // @lc code=end 89 | -------------------------------------------------------------------------------- /230.二叉搜索树中第k小的元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=230 lang=javascript 3 | * 4 | * [230] 二叉搜索树中第K小的元素 5 | * 6 | * https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst/description/ 7 | * 8 | * algorithms 9 | * Medium (65.91%) 10 | * Likes: 89 11 | * Dislikes: 0 12 | * Total Accepted: 19.1K 13 | * Total Submissions: 29.1K 14 | * Testcase Example: '[3,1,4,null,2]\n1' 15 | * 16 | * 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。 17 | * 18 | * 说明: 19 | * 你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。 20 | * 21 | * 示例 1: 22 | * 23 | * 输入: root = [3,1,4,null,2], k = 1 24 | * ⁠ 3 25 | * ⁠ / \ 26 | * ⁠1 4 27 | * ⁠ \ 28 | * 2 29 | * 输出: 1 30 | * 31 | * 示例 2: 32 | * 33 | * 输入: root = [5,3,6,2,4,null,null,1], k = 3 34 | * ⁠ 5 35 | * ⁠ / \ 36 | * ⁠ 3 6 37 | * ⁠ / \ 38 | * ⁠ 2 4 39 | * ⁠ / 40 | * ⁠1 41 | * 输出: 3 42 | * 43 | * 进阶: 44 | * 如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化 kthSmallest 函数? 45 | * 46 | */ 47 | /** 48 | * Definition for a binary tree node. 49 | * function TreeNode(val) { 50 | * this.val = val; 51 | * this.left = this.right = null; 52 | * } 53 | */ 54 | /** 55 | * @param {TreeNode} root 56 | * @param {number} k 57 | * @return {number} 58 | */ 59 | 60 | const kthSmallest = (root, k) => { 61 | const arr = [] 62 | const stack = [] 63 | 64 | let current = root 65 | 66 | while (current || stack.length > 0) { 67 | while (current) { 68 | stack.push(current) 69 | current = current.left 70 | } 71 | 72 | current = stack.pop() 73 | arr.push(current) 74 | current = current.right 75 | } 76 | 77 | if (k > 0 && k <= arr.length) { 78 | return arr[k - 1].val 79 | } 80 | 81 | return null 82 | } 83 | -------------------------------------------------------------------------------- /231.2-的幂.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=231 lang=javascript 3 | * 4 | * [231] 2的幂 5 | */ 6 | /** 7 | * @param {number} n 8 | * @return {boolean} 9 | */ 10 | const isPowerOfTwo = n => { 11 | return n > 0 ? !(n & (n - 1)) : false 12 | } 13 | -------------------------------------------------------------------------------- /232.用栈实现队列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=232 lang=javascript 3 | * 4 | * [232] 用栈实现队列 5 | * 6 | * https://leetcode-cn.com/problems/implement-queue-using-stacks/description/ 7 | * 8 | * algorithms 9 | * Easy (60.92%) 10 | * Likes: 94 11 | * Dislikes: 0 12 | * Total Accepted: 19.1K 13 | * Total Submissions: 31.3K 14 | * Testcase Example: '["MyQueue","push","push","peek","pop","empty"]\n[[],[1],[2],[],[],[]]' 15 | * 16 | * 使用栈实现队列的下列操作: 17 | * 18 | * 19 | * push(x) -- 将一个元素放入队列的尾部。 20 | * pop() -- 从队列首部移除元素。 21 | * peek() -- 返回队列首部的元素。 22 | * empty() -- 返回队列是否为空。 23 | * 24 | * 25 | * 示例: 26 | * 27 | * MyQueue queue = new MyQueue(); 28 | * 29 | * queue.push(1); 30 | * queue.push(2); 31 | * queue.peek(); // 返回 1 32 | * queue.pop(); // 返回 1 33 | * queue.empty(); // 返回 false 34 | * 35 | * 说明: 36 | * 37 | * 38 | * 你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, size, 和 is empty 39 | * 操作是合法的。 40 | * 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。 41 | * 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。 42 | * 43 | * 44 | */ 45 | /** 46 | * Initialize your data structure here. 47 | */ 48 | var MyQueue = function() { 49 | this.stack1 = [] 50 | this.stack2 = [] 51 | } 52 | 53 | /** 54 | * Push element x to the back of queue. 55 | * @param {number} x 56 | * @return {void} 57 | */ 58 | MyQueue.prototype.push = function(x) { 59 | this.stack1.push(x) 60 | } 61 | 62 | /** 63 | * Removes the element from in front of queue and returns that element. 64 | * @return {number} 65 | */ 66 | MyQueue.prototype.pop = function() { 67 | while (this.stack1.length !== 0) { 68 | this.stack2.push(this.stack1.pop()) 69 | } 70 | 71 | let pop = this.stack2.pop() 72 | 73 | while (this.stack2.length !== 0) { 74 | this.stack1.push(this.stack2.pop()) 75 | } 76 | 77 | return pop 78 | } 79 | 80 | /** 81 | * Get the front element. 82 | * @return {number} 83 | */ 84 | MyQueue.prototype.peek = function() { 85 | while (this.stack1.length !== 0) { 86 | this.stack2.push(this.stack1.pop()) 87 | } 88 | 89 | let pop = this.stack2.pop() 90 | this.stack2.push(pop) 91 | 92 | while (this.stack2.length !== 0) { 93 | this.stack1.push(this.stack2.pop()) 94 | } 95 | 96 | return pop 97 | } 98 | 99 | /** 100 | * Returns whether the queue is empty. 101 | * @return {boolean} 102 | */ 103 | MyQueue.prototype.empty = function() { 104 | return this.stack1.length === 0 ? true : false 105 | } 106 | 107 | /** 108 | * Your MyQueue object will be instantiated and called as such: 109 | * var obj = new MyQueue() 110 | * obj.push(x) 111 | * var param_2 = obj.pop() 112 | * var param_3 = obj.peek() 113 | * var param_4 = obj.empty() 114 | */ 115 | -------------------------------------------------------------------------------- /234.回文链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=234 lang=javascript 3 | * 4 | * [234] 回文链表 5 | * 6 | * https://leetcode-cn.com/problems/palindrome-linked-list/description/ 7 | * 8 | * algorithms 9 | * Easy (38.45%) 10 | * Likes: 276 11 | * Dislikes: 0 12 | * Total Accepted: 40.6K 13 | * Total Submissions: 104.5K 14 | * Testcase Example: '[1,2]' 15 | * 16 | * 请判断一个链表是否为回文链表。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: 1->2 21 | * 输出: false 22 | * 23 | * 示例 2: 24 | * 25 | * 输入: 1->2->2->1 26 | * 输出: true 27 | * 28 | * 29 | * 进阶: 30 | * 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题? 31 | * 32 | */ 33 | /** 34 | * Definition for singly-linked list. 35 | * function ListNode(val) { 36 | * this.val = val; 37 | * this.next = null; 38 | * } 39 | */ 40 | /** 41 | * @param {ListNode} head 42 | * @return {boolean} 43 | */ 44 | const reverseList = head => { 45 | if (!head) { 46 | return null 47 | } 48 | 49 | let pre = null 50 | let next = null 51 | 52 | while (head) { 53 | next = head.next 54 | head.next = pre 55 | pre = head 56 | head = next 57 | } 58 | 59 | return pre 60 | } 61 | const isPalindrome = head => { 62 | if (head === null || head.next === null) { 63 | return true 64 | } 65 | 66 | let slow = head 67 | let fast = head 68 | 69 | while (fast.next !== null && fast.next.next !== null) { 70 | slow = slow.next 71 | fast = fast.next.next 72 | } 73 | 74 | slow.next = reverseList(slow.next) 75 | slow = slow.next 76 | 77 | while(slow !== null) { 78 | if (head.val !== slow.val) { 79 | return false 80 | } 81 | 82 | head = head.next 83 | slow = slow.next 84 | } 85 | 86 | return true 87 | } 88 | -------------------------------------------------------------------------------- /235.二叉搜索树的最近公共祖先.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=235 lang=javascript 3 | * 4 | * [235] 二叉搜索树的最近公共祖先 5 | * 6 | * https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree/description/ 7 | * 8 | * algorithms 9 | * Easy (60.47%) 10 | * Likes: 145 11 | * Dislikes: 0 12 | * Total Accepted: 21.7K 13 | * Total Submissions: 36K 14 | * Testcase Example: '[6,2,8,0,4,7,9,null,null,3,5]\n2\n8' 15 | * 16 | * 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 17 | * 18 | * 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 19 | * 的深度尽可能大(一个节点也可以是它自己的祖先)。” 20 | * 21 | * 例如,给定如下二叉搜索树:  root = [6,2,8,0,4,7,9,null,null,3,5] 22 | * 23 | * 24 | * 25 | * 26 | * 27 | * 示例 1: 28 | * 29 | * 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 30 | * 输出: 6 31 | * 解释: 节点 2 和节点 8 的最近公共祖先是 6。 32 | * 33 | * 34 | * 示例 2: 35 | * 36 | * 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4 37 | * 输出: 2 38 | * 解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。 39 | * 40 | * 41 | * 42 | * 说明: 43 | * 44 | * 45 | * 所有节点的值都是唯一的。 46 | * p、q 为不同节点且均存在于给定的二叉搜索树中。 47 | * 48 | * 49 | */ 50 | /** 51 | * Definition for a binary tree node. 52 | * function TreeNode(val) { 53 | * this.val = val; 54 | * this.left = this.right = null; 55 | * } 56 | */ 57 | /** 58 | * @param {TreeNode} root 59 | * @param {TreeNode} p 60 | * @param {TreeNode} q 61 | * @return {TreeNode} 62 | */ 63 | 64 | const lowestCommonAncestor = (root, p, q) => { 65 | if (p.val > root.val && q.val > root.val) { 66 | return lowestCommonAncestor(root.right, p, q) 67 | } else if (p.val < root.val && q.val < root.val) { 68 | return lowestCommonAncestor(root.left, p, q) 69 | } else { 70 | return root 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /236.二叉树的最近公共祖先.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=236 lang=javascript 3 | * 4 | * [236] 二叉树的最近公共祖先 5 | * 6 | * https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/description/ 7 | * 8 | * algorithms 9 | * Medium (57.11%) 10 | * Likes: 228 11 | * Dislikes: 0 12 | * Total Accepted: 22.3K 13 | * Total Submissions: 39.1K 14 | * Testcase Example: '[3,5,1,6,2,0,8,null,null,7,4]\n5\n1' 15 | * 16 | * 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 17 | * 18 | * 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 19 | * 的深度尽可能大(一个节点也可以是它自己的祖先)。” 20 | * 21 | * 例如,给定如下二叉树:  root = [3,5,1,6,2,0,8,null,null,7,4] 22 | * 23 | * 24 | * 25 | * 26 | * 27 | * 示例 1: 28 | * 29 | * 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 30 | * 输出: 3 31 | * 解释: 节点 5 和节点 1 的最近公共祖先是节点 3。 32 | * 33 | * 34 | * 示例 2: 35 | * 36 | * 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 37 | * 输出: 5 38 | * 解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。 39 | * 40 | * 41 | * 42 | * 43 | * 说明: 44 | * 45 | * 46 | * 所有节点的值都是唯一的。 47 | * p、q 为不同节点且均存在于给定的二叉树中。 48 | * 49 | * 50 | */ 51 | /** 52 | * Definition for a binary tree node. 53 | * function TreeNode(val) { 54 | * this.val = val; 55 | * this.left = this.right = null; 56 | * } 57 | */ 58 | /** 59 | * @param {TreeNode} root 60 | * @param {TreeNode} p 61 | * @param {TreeNode} q 62 | * @return {TreeNode} 63 | */ 64 | const lowestCommonAncestor = (root, p, q) => { 65 | if (!root || root === p || root === q) { 66 | return root 67 | } 68 | 69 | const left = lowestCommonAncestor(root.left, p, q) 70 | const right = lowestCommonAncestor(root.right, p, q) 71 | 72 | if (!left) { 73 | return right 74 | } 75 | 76 | if (!right) { 77 | return left 78 | } 79 | 80 | return root 81 | } 82 | -------------------------------------------------------------------------------- /237.删除链表中的节点.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=237 lang=javascript 3 | * 4 | * [237] 删除链表中的节点 5 | * 6 | * https://leetcode-cn.com/problems/delete-node-in-a-linked-list/description/ 7 | * 8 | * algorithms 9 | * Easy (76.45%) 10 | * Likes: 440 11 | * Dislikes: 0 12 | * Total Accepted: 48.1K 13 | * Total Submissions: 62.6K 14 | * Testcase Example: '[4,5,1,9]\n5' 15 | * 16 | * 请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点。 17 | * 18 | * 现有一个链表 -- head = [4,5,1,9],它可以表示为: 19 | * 20 | * 21 | * 22 | * 23 | * 24 | * 示例 1: 25 | * 26 | * 输入: head = [4,5,1,9], node = 5 27 | * 输出: [4,1,9] 28 | * 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9. 29 | * 30 | * 31 | * 示例 2: 32 | * 33 | * 输入: head = [4,5,1,9], node = 1 34 | * 输出: [4,5,9] 35 | * 解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9. 36 | * 37 | * 38 | * 39 | * 40 | * 说明: 41 | * 42 | * 43 | * 链表至少包含两个节点。 44 | * 链表中所有节点的值都是唯一的。 45 | * 给定的节点为非末尾节点并且一定是链表中的一个有效节点。 46 | * 不要从你的函数中返回任何结果。 47 | * 48 | * 49 | */ 50 | /** 51 | * Definition for singly-linked list. 52 | * function ListNode(val) { 53 | * this.val = val; 54 | * this.next = null; 55 | * } 56 | */ 57 | /** 58 | * @param {ListNode} node 59 | * @return {void} Do not return anything, modify node in-place instead. 60 | */ 61 | const deleteNode = node => { 62 | node.val = node.next.val 63 | node.next = node.next.next 64 | } 65 | -------------------------------------------------------------------------------- /238.除自身以外数组的乘积.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=238 lang=javascript 3 | * 4 | * [238] 除自身以外数组的乘积 5 | * 6 | * https://leetcode-cn.com/problems/product-of-array-except-self/description/ 7 | * 8 | * algorithms 9 | * Medium (62.86%) 10 | * Likes: 218 11 | * Dislikes: 0 12 | * Total Accepted: 18.1K 13 | * Total Submissions: 28.6K 14 | * Testcase Example: '[1,2,3,4]' 15 | * 16 | * 给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 17 | * 之外其余各元素的乘积。 18 | * 19 | * 示例: 20 | * 21 | * 输入: [1,2,3,4] 22 | * 输出: [24,12,8,6] 23 | * 24 | * 说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。 25 | * 26 | * 进阶: 27 | * 你可以在常数空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。) 28 | * 29 | */ 30 | 31 | // @lc code=start 32 | /** 33 | * @param {number[]} nums 34 | * @return {number[]} 35 | */ 36 | const productExceptSelf = nums => { 37 | let res = [] 38 | let prod = 1 39 | 40 | for (let i = 0; i < nums.length; i++) { 41 | res[i] = prod 42 | prod *= nums[i] 43 | } 44 | 45 | prod = 1 46 | 47 | for (let i = nums.length - 1; i >= 0; i--) { 48 | res[i] *= prod 49 | prod *= nums[i] 50 | } 51 | 52 | return res 53 | } 54 | // @lc code=end 55 | -------------------------------------------------------------------------------- /24.两两交换链表中的节点.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=24 lang=javascript 3 | * 4 | * [24] 两两交换链表中的节点 5 | * 6 | * https://leetcode-cn.com/problems/swap-nodes-in-pairs/description/ 7 | * 8 | * algorithms 9 | * Medium (63.12%) 10 | * Likes: 357 11 | * Dislikes: 0 12 | * Total Accepted: 57.9K 13 | * Total Submissions: 91.4K 14 | * Testcase Example: '[1,2,3,4]' 15 | * 16 | * 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 17 | * 18 | * 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 19 | * 20 | * 21 | * 22 | * 示例: 23 | * 24 | * 给定 1->2->3->4, 你应该返回 2->1->4->3. 25 | * 26 | * 27 | */ 28 | 29 | // @lc code=start 30 | /** 31 | * Definition for singly-linked list. 32 | * function ListNode(val) { 33 | * this.val = val; 34 | * this.next = null; 35 | * } 36 | */ 37 | /** 38 | * @param {ListNode} head 39 | * @return {ListNode} 40 | */ 41 | const swapPairs = function (head) { 42 | if (!head || !head.next) { 43 | return head 44 | } 45 | 46 | let v1 = head 47 | let v2 = head.next 48 | let v3 = v2.next 49 | 50 | v2.next = v1 51 | v1.next = swapPairs(v3) 52 | 53 | return v2 54 | } 55 | // @lc code=end 56 | -------------------------------------------------------------------------------- /242.有效的字母异位词.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=242 lang=javascript 3 | * 4 | * [242] 有效的字母异位词 5 | * 6 | * https://leetcode-cn.com/problems/valid-anagram/description/ 7 | * 8 | * algorithms 9 | * Easy (55.20%) 10 | * Likes: 113 11 | * Dislikes: 0 12 | * Total Accepted: 47.8K 13 | * Total Submissions: 85.7K 14 | * Testcase Example: '"anagram"\n"nagaram"' 15 | * 16 | * 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: s = "anagram", t = "nagaram" 21 | * 输出: true 22 | * 23 | * 24 | * 示例 2: 25 | * 26 | * 输入: s = "rat", t = "car" 27 | * 输出: false 28 | * 29 | * 说明: 30 | * 你可以假设字符串只包含小写字母。 31 | * 32 | * 进阶: 33 | * 如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况? 34 | * 35 | */ 36 | /** 37 | * @param {string} s 38 | * @param {string} t 39 | * @return {boolean} 40 | */ 41 | const isAnagram = (s, t) => { 42 | const map = {} 43 | 44 | s.split('').map(c => (map[c] = map[c] ? map[c] + 1 : 1)) 45 | t.split('').map(c => (map[c] = map[c] ? map[c] - 1 : -1)) 46 | 47 | return Object.keys(map).every(k => map[k] === 0) 48 | } 49 | -------------------------------------------------------------------------------- /25.k-个一组翻转链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=25 lang=javascript 3 | * 4 | * [25] K 个一组翻转链表 5 | * 6 | * https://leetcode-cn.com/problems/reverse-nodes-in-k-group/description/ 7 | * 8 | * algorithms 9 | * Hard (55.25%) 10 | * Likes: 323 11 | * Dislikes: 0 12 | * Total Accepted: 30.7K 13 | * Total Submissions: 55.6K 14 | * Testcase Example: '[1,2,3,4,5]\n2' 15 | * 16 | * 给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。 17 | * 18 | * k 是一个正整数,它的值小于或等于链表的长度。 19 | * 20 | * 如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。 21 | * 22 | * 示例 : 23 | * 24 | * 给定这个链表:1->2->3->4->5 25 | * 26 | * 当 k = 2 时,应当返回: 2->1->4->3->5 27 | * 28 | * 当 k = 3 时,应当返回: 3->2->1->4->5 29 | * 30 | * 说明 : 31 | * 32 | * 33 | * 你的算法只能使用常数的额外空间。 34 | * 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 35 | * 36 | * 37 | */ 38 | 39 | // @lc code=start 40 | /** 41 | * Definition for singly-linked list. 42 | * function ListNode(val) { 43 | * this.val = val; 44 | * this.next = null; 45 | * } 46 | */ 47 | 48 | function reverse(curr) { 49 | let prev = null 50 | 51 | while (curr) { 52 | let next = curr.next 53 | curr.next = prev 54 | prev = curr 55 | curr = next 56 | } 57 | 58 | return prev 59 | } 60 | 61 | /** 62 | * @param {ListNode} head 63 | * @param {number} k 64 | * @return {ListNode} 65 | */ 66 | const reverseKGroup = function reverseKGroup(head, k) { 67 | if (!head) { 68 | return null 69 | } 70 | 71 | let tail = head 72 | 73 | for (let i = 1; i < k; i++) { 74 | tail = tail.next 75 | if (!tail) { 76 | return head 77 | } 78 | } 79 | 80 | let next = tail.next 81 | tail.next = null 82 | reverse(head) 83 | head.next = reverseKGroup(next, k) 84 | 85 | return tail 86 | } 87 | // @lc code=end 88 | -------------------------------------------------------------------------------- /26.删除排序数组中的重复项.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=26 lang=javascript 3 | * 4 | * [26] 删除排序数组中的重复项 5 | * 6 | * https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/description/ 7 | * 8 | * algorithms 9 | * Easy (45.84%) 10 | * Likes: 1034 11 | * Dislikes: 0 12 | * Total Accepted: 154.2K 13 | * Total Submissions: 335.7K 14 | * Testcase Example: '[1,1,2]' 15 | * 16 | * 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。 17 | * 18 | * 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 19 | * 20 | * 示例 1: 21 | * 22 | * 给定数组 nums = [1,1,2], 23 | * 24 | * 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 25 | * 26 | * 你不需要考虑数组中超出新长度后面的元素。 27 | * 28 | * 示例 2: 29 | * 30 | * 给定 nums = [0,0,1,1,1,2,2,3,3,4], 31 | * 32 | * 函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。 33 | * 34 | * 你不需要考虑数组中超出新长度后面的元素。 35 | * 36 | * 37 | * 说明: 38 | * 39 | * 为什么返回数值是整数,但输出的答案是数组呢? 40 | * 41 | * 请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 42 | * 43 | * 你可以想象内部操作如下: 44 | * 45 | * // nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝 46 | * int len = removeDuplicates(nums); 47 | * 48 | * // 在函数里修改输入数组对于调用者是可见的。 49 | * // 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。 50 | * for (int i = 0; i < len; i++) { 51 | * print(nums[i]); 52 | * } 53 | * 54 | * 55 | */ 56 | /** 57 | * @param {number[]} nums 58 | * @return {number} 59 | */ 60 | const removeDuplicates = nums => { 61 | for (let i = 0; i < nums.length; i++) { 62 | if (nums[i] === nums[i - 1]) { 63 | nums.splice(i, 1) 64 | i-- 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /268.缺失数字.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=268 lang=javascript 3 | * 4 | * [268] 缺失数字 5 | * 6 | * https://leetcode-cn.com/problems/missing-number/description/ 7 | * 8 | * algorithms 9 | * Easy (52.10%) 10 | * Likes: 169 11 | * Dislikes: 0 12 | * Total Accepted: 33.4K 13 | * Total Submissions: 63.4K 14 | * Testcase Example: '[3,0,1]' 15 | * 16 | * 给定一个包含 0, 1, 2, ..., n 中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: [3,0,1] 21 | * 输出: 2 22 | * 23 | * 24 | * 示例 2: 25 | * 26 | * 输入: [9,6,4,2,3,5,7,0,1] 27 | * 输出: 8 28 | * 29 | * 30 | * 说明: 31 | * 你的算法应具有线性时间复杂度。你能否仅使用额外常数空间来实现? 32 | * 33 | */ 34 | /** 35 | * @param {number[]} nums 36 | * @return {number} 37 | */ 38 | const missingNumber = nums => { 39 | const hash = {} 40 | let l = nums.length 41 | 42 | nums.map(item => { 43 | hash[item] = item 44 | }) 45 | 46 | let res = null 47 | 48 | for (let i = 0; i < l; i++) { 49 | if (hash[i] === undefined) { 50 | res = i 51 | } 52 | } 53 | 54 | if (res === null) { 55 | res = l 56 | } 57 | 58 | return res 59 | } 60 | -------------------------------------------------------------------------------- /27.移除元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=27 lang=javascript 3 | * 4 | * [27] 移除元素 5 | * 6 | * https://leetcode-cn.com/problems/remove-element/description/ 7 | * 8 | * algorithms 9 | * Easy (56.60%) 10 | * Likes: 432 11 | * Dislikes: 0 12 | * Total Accepted: 112.7K 13 | * Total Submissions: 198.9K 14 | * Testcase Example: '[3,2,2,3]\n3' 15 | * 16 | * 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。 17 | * 18 | * 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 19 | * 20 | * 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 21 | * 22 | * 示例 1: 23 | * 24 | * 给定 nums = [3,2,2,3], val = 3, 25 | * 26 | * 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 27 | * 28 | * 你不需要考虑数组中超出新长度后面的元素。 29 | * 30 | * 31 | * 示例 2: 32 | * 33 | * 给定 nums = [0,1,2,2,3,0,4,2], val = 2, 34 | * 35 | * 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。 36 | * 37 | * 注意这五个元素可为任意顺序。 38 | * 39 | * 你不需要考虑数组中超出新长度后面的元素。 40 | * 41 | * 42 | * 说明: 43 | * 44 | * 为什么返回数值是整数,但输出的答案是数组呢? 45 | * 46 | * 请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 47 | * 48 | * 你可以想象内部操作如下: 49 | * 50 | * // nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝 51 | * int len = removeElement(nums, val); 52 | * 53 | * // 在函数里修改输入数组对于调用者是可见的。 54 | * // 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。 55 | * for (int i = 0; i < len; i++) { 56 | * print(nums[i]); 57 | * } 58 | * 59 | * 60 | */ 61 | 62 | // @lc code=start 63 | /** 64 | * @param {number[]} nums 65 | * @param {number} val 66 | * @return {number} 67 | * @description 快慢指针解法 68 | */ 69 | const removeElement = function (nums, val) { 70 | let slow = 0 71 | 72 | for (let quick = 0; quick < nums.length; quick++) { 73 | if (nums[quick] !== val) { 74 | nums[slow] = nums[quick] 75 | slow++ 76 | } 77 | } 78 | 79 | return slow 80 | } 81 | // @lc code=end 82 | -------------------------------------------------------------------------------- /278.第一个错误的版本.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=278 lang=javascript 3 | * 4 | * [278] 第一个错误的版本 5 | * 6 | * https://leetcode-cn.com/problems/first-bad-version/description/ 7 | * 8 | * algorithms 9 | * Easy (34.99%) 10 | * Likes: 144 11 | * Dislikes: 0 12 | * Total Accepted: 39.1K 13 | * Total Submissions: 104.8K 14 | * Testcase Example: '5\n4' 15 | * 16 | * 17 | * 你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。 18 | * 19 | * 假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。 20 | * 21 | * 你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 22 | * 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。 23 | * 24 | * 示例: 25 | * 26 | * 给定 n = 5,并且 version = 4 是第一个错误的版本。 27 | * 28 | * 调用 isBadVersion(3) -> false 29 | * 调用 isBadVersion(5) -> true 30 | * 调用 isBadVersion(4) -> true 31 | * 32 | * 所以,4 是第一个错误的版本。 33 | * 34 | */ 35 | 36 | // @lc code=start 37 | /** 38 | * Definition for isBadVersion() 39 | * 40 | * @param {integer} version number 41 | * @return {boolean} whether the version is bad 42 | * isBadVersion = function(version) { 43 | * ... 44 | * }; 45 | */ 46 | 47 | /** 48 | * @param {function} isBadVersion() 49 | * @return {function} 50 | */ 51 | const solution = function(isBadVersion) { 52 | /** 53 | * @param {integer} n Total versions 54 | * @return {integer} The first bad version 55 | */ 56 | return function(n) { 57 | let left = 1 58 | let right = n 59 | 60 | while (left < right) { 61 | let mid = left + ((right - left) >> 1) 62 | 63 | if (isBadVersion(mid)) { 64 | right = mid 65 | } else { 66 | left = mid + 1 67 | } 68 | } 69 | 70 | return left 71 | } 72 | } 73 | // @lc code=end 74 | -------------------------------------------------------------------------------- /279.完全平方数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=279 lang=javascript 3 | * 4 | * [279] 完全平方数 5 | * 6 | * https://leetcode-cn.com/problems/perfect-squares/description/ 7 | * 8 | * algorithms 9 | * Medium (51.28%) 10 | * Likes: 260 11 | * Dislikes: 0 12 | * Total Accepted: 29.3K 13 | * Total Submissions: 56.5K 14 | * Testcase Example: '12' 15 | * 16 | * 给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: n = 12 21 | * 输出: 3 22 | * 解释: 12 = 4 + 4 + 4. 23 | * 24 | * 示例 2: 25 | * 26 | * 输入: n = 13 27 | * 输出: 2 28 | * 解释: 13 = 4 + 9. 29 | * 30 | */ 31 | 32 | // @lc code=start 33 | /** 34 | * @param {number} n 35 | * @return {number} 36 | */ 37 | var numSquares = function(n) {} 38 | // @lc code=end 39 | -------------------------------------------------------------------------------- /28.实现-str-str.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=28 lang=javascript 3 | * 4 | * [28] 实现 strStr() 5 | * 6 | * https://leetcode-cn.com/problems/implement-strstr/description/ 7 | * 8 | * algorithms 9 | * Easy (38.71%) 10 | * Likes: 268 11 | * Dislikes: 0 12 | * Total Accepted: 86.7K 13 | * Total Submissions: 222.5K 14 | * Testcase Example: '"hello"\n"ll"' 15 | * 16 | * 实现 strStr() 函数。 17 | * 18 | * 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 19 | * (从0开始)。如果不存在,则返回  -1。 20 | * 21 | * 示例 1: 22 | * 23 | * 输入: haystack = "hello", needle = "ll" 24 | * 输出: 2 25 | * 26 | * 27 | * 示例 2: 28 | * 29 | * 输入: haystack = "aaaaa", needle = "bba" 30 | * 输出: -1 31 | * 32 | * 33 | * 说明: 34 | * 35 | * 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 36 | * 37 | * 对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。 38 | * 39 | */ 40 | /** 41 | * @param {string} haystack 42 | * @param {string} needle 43 | * @return {number} 44 | */ 45 | // TODO: 46 | const strStr = (haystack, needle) => { 47 | if (needle === '') { 48 | return 0 49 | } 50 | 51 | for (let i = 0; i < haystack.length; i++) { 52 | if (haystack[i] === needle[0]) { 53 | if (haystack.substring(i, i + needle.length) === needle) { 54 | return i 55 | } 56 | } 57 | } 58 | 59 | return -1 60 | } 61 | -------------------------------------------------------------------------------- /283.移动零.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=283 lang=javascript 3 | * 4 | * [283] 移动零 5 | * 6 | * https://leetcode-cn.com/problems/move-zeroes/description/ 7 | * 8 | * algorithms 9 | * Easy (56.42%) 10 | * Likes: 391 11 | * Dislikes: 0 12 | * Total Accepted: 69.5K 13 | * Total Submissions: 122.7K 14 | * Testcase Example: '[0,1,0,3,12]' 15 | * 16 | * 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 17 | * 18 | * 示例: 19 | * 20 | * 输入: [0,1,0,3,12] 21 | * 输出: [1,3,12,0,0] 22 | * 23 | * 说明: 24 | * 25 | * 26 | * 必须在原数组上操作,不能拷贝额外的数组。 27 | * 尽量减少操作次数。 28 | * 29 | * 30 | */ 31 | /** 32 | * @param {number[]} nums 33 | * @return {void} Do not return anything, modify nums in-place instead. 34 | */ 35 | const moveZeroes = function(nums) { 36 | for (let i = nums.length - 1; i >= 0; i--) { 37 | if (nums[i] === 0) { 38 | nums.splice(i, 1) 39 | nums.push(0) 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /287.寻找重复数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=287 lang=javascript 3 | * 4 | * [287] 寻找重复数 5 | * 6 | * https://leetcode-cn.com/problems/find-the-duplicate-number/description/ 7 | * 8 | * algorithms 9 | * Medium (60.56%) 10 | * Likes: 268 11 | * Dislikes: 0 12 | * Total Accepted: 20K 13 | * Total Submissions: 32.8K 14 | * Testcase Example: '[1,3,4,2,2]' 15 | * 16 | * 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 17 | * n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。 18 | * 19 | * 示例 1: 20 | * 21 | * 输入: [1,3,4,2,2] 22 | * 输出: 2 23 | * 24 | * 25 | * 示例 2: 26 | * 27 | * 输入: [3,1,3,4,2] 28 | * 输出: 3 29 | * 30 | * 31 | * 说明: 32 | * 33 | * 34 | * 不能更改原数组(假设数组是只读的)。 35 | * 只能使用额外的 O(1) 的空间。 36 | * 时间复杂度小于 O(n^2) 。 37 | * 数组中只有一个重复的数字,但它可能不止重复出现一次。 38 | * 39 | * 40 | */ 41 | /** 42 | * @param {number[]} nums 43 | * @return {number} 44 | */ 45 | const findDuplicate = nums => { 46 | const hash = {} 47 | 48 | for (const n of nums) { 49 | if (hash[n]) { 50 | return n 51 | } else { 52 | hash[n] = true 53 | } 54 | } 55 | 56 | return null 57 | } 58 | -------------------------------------------------------------------------------- /29.两数相除.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=29 lang=javascript 3 | * 4 | * [29] 两数相除 5 | * 6 | * https://leetcode-cn.com/problems/divide-two-integers/description/ 7 | * 8 | * algorithms 9 | * Medium (18.81%) 10 | * Likes: 240 11 | * Dislikes: 0 12 | * Total Accepted: 29.4K 13 | * Total Submissions: 154.6K 14 | * Testcase Example: '10\n3' 15 | * 16 | * 给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。 17 | * 18 | * 返回被除数 dividend 除以除数 divisor 得到的商。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: dividend = 10, divisor = 3 23 | * 输出: 3 24 | * 25 | * 示例 2: 26 | * 27 | * 输入: dividend = 7, divisor = -3 28 | * 输出: -2 29 | * 30 | * 说明: 31 | * 32 | * 33 | * 被除数和除数均为 32 位有符号整数。 34 | * 除数不为 0。 35 | * 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−2^31,  2^31 − 1]。本题中,如果除法结果溢出,则返回 2^31 − 1。 36 | * 37 | * 38 | */ 39 | 40 | // @lc code=start 41 | /** 42 | * @param {number} dividend 43 | * @param {number} divisor 44 | * @return {number} 45 | */ 46 | const divide = function (dividend, divisor) { 47 | if (divisor === 0) return 0 48 | if (dividend === 0) return 0 49 | if (dividend === -2147483648 && divisor === -1) return 2147483647 50 | 51 | let isPositive = true 52 | if (dividend > 0 !== divisor > 0) isPositive = false 53 | 54 | divisor = Math.abs(divisor) 55 | dividend = Math.abs(dividend) 56 | 57 | let count = 1, 58 | result = 0, 59 | base = divisor 60 | 61 | while (dividend >= divisor) { 62 | count = 1 63 | base = divisor 64 | while (base <= dividend >> 1) { 65 | base = base << 1 66 | count = count << 1 67 | } 68 | result += count 69 | dividend -= base 70 | } 71 | 72 | if (!isPositive) result = -result 73 | return result 74 | } 75 | // @lc code=end 76 | -------------------------------------------------------------------------------- /292.nim-游戏.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=292 lang=javascript 3 | * 4 | * [292] Nim 游戏 5 | */ 6 | /** 7 | * @param {number} n 8 | * @return {boolean} 9 | */ 10 | const canWinNim = n => { 11 | return n % 4 !== 0 12 | } 13 | -------------------------------------------------------------------------------- /3.无重复字符的最长子串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=3 lang=javascript 3 | * 4 | * [3] 无重复字符的最长子串 5 | * 6 | * https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/description/ 7 | * 8 | * algorithms 9 | * Medium (30.92%) 10 | * Likes: 2297 11 | * Dislikes: 0 12 | * Total Accepted: 195K 13 | * Total Submissions: 628.3K 14 | * Testcase Example: '"abcabcbb"' 15 | * 16 | * 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: "abcabcbb" 21 | * 输出: 3 22 | * 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 23 | * 24 | * 25 | * 示例 2: 26 | * 27 | * 输入: "bbbbb" 28 | * 输出: 1 29 | * 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 30 | * 31 | * 32 | * 示例 3: 33 | * 34 | * 输入: "pwwkew" 35 | * 输出: 3 36 | * 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 37 | * 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。 38 | * 39 | * 40 | */ 41 | /** 42 | * @param {string} s 43 | * @return {number} 44 | */ 45 | const lengthOfLongestSubstring = s => { 46 | const map = {} 47 | let left = 0 48 | 49 | return s.split('').reduce((max, v, i) => { 50 | left = map[v] >= left ? map[v] + 1 : left 51 | map[v] = i 52 | 53 | return Math.max(max, i - left + 1) 54 | }, 0) 55 | } 56 | -------------------------------------------------------------------------------- /300.最长上升子序列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=300 lang=javascript 3 | * 4 | * [300] 最长上升子序列 5 | * 6 | * https://leetcode-cn.com/problems/longest-increasing-subsequence/description/ 7 | * 8 | * algorithms 9 | * Medium (43.28%) 10 | * Likes: 320 11 | * Dislikes: 0 12 | * Total Accepted: 31.8K 13 | * Total Submissions: 73.4K 14 | * Testcase Example: '[10,9,2,5,3,7,101,18]' 15 | * 16 | * 给定一个无序的整数数组,找到其中最长上升子序列的长度。 17 | * 18 | * 示例: 19 | * 20 | * 输入: [10,9,2,5,3,7,101,18] 21 | * 输出: 4 22 | * 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 23 | * 24 | * 说明: 25 | * 26 | * 27 | * 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。 28 | * 你算法的时间复杂度应该为 O(n^2) 。 29 | * 30 | * 31 | * 进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗? 32 | * 33 | */ 34 | 35 | // @lc code=start 36 | /** 37 | * @param {number[]} nums 38 | * @return {number} 39 | */ 40 | // TODO: 41 | const lengthOfLIS = (nums) => { 42 | const lis = [] 43 | 44 | for (let i = 0; i < nums.length; i++) { 45 | lis.push(1) 46 | 47 | for (let j = 0; j < i; j++) { 48 | if (nums[j] < nums[i]) lis[i] = Math.max(lis[i], lis[j] + 1) 49 | } 50 | } 51 | 52 | return nums.length ? Math.max.apply(null, lis) : 0 53 | } 54 | // @lc code=end 55 | -------------------------------------------------------------------------------- /326.3-的幂.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=326 lang=javascript 3 | * 4 | * [326] 3的幂 5 | * 6 | * https://leetcode-cn.com/problems/power-of-three/description/ 7 | * 8 | * algorithms 9 | * Easy (44.96%) 10 | * Likes: 72 11 | * Dislikes: 0 12 | * Total Accepted: 26.1K 13 | * Total Submissions: 57.8K 14 | * Testcase Example: '27' 15 | * 16 | * 给定一个整数,写一个函数来判断它是否是 3 的幂次方。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: 27 21 | * 输出: true 22 | * 23 | * 24 | * 示例 2: 25 | * 26 | * 输入: 0 27 | * 输出: false 28 | * 29 | * 示例 3: 30 | * 31 | * 输入: 9 32 | * 输出: true 33 | * 34 | * 示例 4: 35 | * 36 | * 输入: 45 37 | * 输出: false 38 | * 39 | * 进阶: 40 | * 你能不使用循环或者递归来完成本题吗? 41 | * 42 | */ 43 | /** 44 | * @param {number} n 45 | * @return {boolean} 46 | */ 47 | const isPowerOfThree = n => { 48 | return ( 49 | n 50 | .toString(3) 51 | .split('') 52 | .reduce((prev, curr) => parseInt(prev) + parseInt(curr)) == 1 53 | ) 54 | } 55 | -------------------------------------------------------------------------------- /328.奇偶链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=328 lang=javascript 3 | * 4 | * [328] 奇偶链表 5 | * 6 | * https://leetcode-cn.com/problems/odd-even-linked-list/description/ 7 | * 8 | * algorithms 9 | * Medium (59.60%) 10 | * Likes: 107 11 | * Dislikes: 0 12 | * Total Accepted: 20.6K 13 | * Total Submissions: 34.4K 14 | * Testcase Example: '[1,2,3,4,5]' 15 | * 16 | * 给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。 17 | * 18 | * 请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: 1->2->3->4->5->NULL 23 | * 输出: 1->3->5->2->4->NULL 24 | * 25 | * 26 | * 示例 2: 27 | * 28 | * 输入: 2->1->3->5->6->4->7->NULL 29 | * 输出: 2->3->6->7->1->5->4->NULL 30 | * 31 | * 说明: 32 | * 33 | * 34 | * 应当保持奇数节点和偶数节点的相对顺序。 35 | * 链表的第一个节点视为奇数节点,第二个节点视为偶数节点,以此类推。 36 | * 37 | * 38 | */ 39 | 40 | // @lc code=start 41 | /** 42 | * Definition for singly-linked list. 43 | * function ListNode(val) { 44 | * this.val = val; 45 | * this.next = null; 46 | * } 47 | */ 48 | /** 49 | * @param {ListNode} head 50 | * @return {ListNode} 51 | */ 52 | const oddEvenList = function(head) { 53 | if (!head) { 54 | return head 55 | } 56 | 57 | let odd = head 58 | let even = head.next 59 | let evenHead = even 60 | 61 | while (even !== null && even.next !== null) { 62 | odd.next = even.next 63 | odd = odd.next 64 | even.next = odd.next 65 | even = even.next 66 | } 67 | 68 | odd.next = evenHead 69 | 70 | return head 71 | } 72 | // @lc code=end 73 | -------------------------------------------------------------------------------- /33.搜索旋转排序数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=33 lang=javascript 3 | * 4 | * [33] 搜索旋转排序数组 5 | * 6 | * https://leetcode-cn.com/problems/search-in-rotated-sorted-array/description/ 7 | * 8 | * algorithms 9 | * Medium (36.12%) 10 | * Likes: 370 11 | * Dislikes: 0 12 | * Total Accepted: 45.7K 13 | * Total Submissions: 126.6K 14 | * Testcase Example: '[4,5,6,7,0,1,2]\n0' 15 | * 16 | * 假设按照升序排序的数组在预先未知的某个点上进行了旋转。 17 | * 18 | * ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 19 | * 20 | * 搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。 21 | * 22 | * 你可以假设数组中不存在重复的元素。 23 | * 24 | * 你的算法时间复杂度必须是 O(log n) 级别。 25 | * 26 | * 示例 1: 27 | * 28 | * 输入: nums = [4,5,6,7,0,1,2], target = 0 29 | * 输出: 4 30 | * 31 | * 32 | * 示例 2: 33 | * 34 | * 输入: nums = [4,5,6,7,0,1,2], target = 3 35 | * 输出: -1 36 | * 37 | */ 38 | 39 | // @lc code=start 40 | /** 41 | * @param {number[]} nums 42 | * @param {number} target 43 | * @return {number} 44 | */ 45 | const search = (nums, target) => { 46 | let start = 0 47 | let end = nums.length - 1 48 | 49 | while (start <= end) { 50 | const mid = start + ((end - start) >> 1) 51 | 52 | if (nums[mid] === target) { 53 | return mid 54 | } 55 | 56 | if (nums[mid] >= nums[start]) { 57 | if (target >= nums[start] && target <= nums[mid]) { 58 | end = mid - 1 59 | } else { 60 | start = mid + 1 61 | } 62 | } else { 63 | if (target >= nums[mid] && target <= nums[end]) { 64 | start = mid + 1 65 | } else { 66 | end = mid - 1 67 | } 68 | } 69 | } 70 | 71 | return -1 72 | } 73 | // @lc code=end 74 | -------------------------------------------------------------------------------- /34.在排序数组中查找元素的第一个和最后一个位置.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=34 lang=javascript 3 | * 4 | * [34] 在排序数组中查找元素的第一个和最后一个位置 5 | * 6 | * https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/description/ 7 | * 8 | * algorithms 9 | * Medium (38.15%) 10 | * Likes: 343 11 | * Dislikes: 0 12 | * Total Accepted: 71.2K 13 | * Total Submissions: 181.7K 14 | * Testcase Example: '[5,7,7,8,8,10]\n8' 15 | * 16 | * 给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 17 | * 18 | * 你的算法时间复杂度必须是 O(log n) 级别。 19 | * 20 | * 如果数组中不存在目标值,返回 [-1, -1]。 21 | * 22 | * 示例 1: 23 | * 24 | * 输入: nums = [5,7,7,8,8,10], target = 8 25 | * 输出: [3,4] 26 | * 27 | * 示例 2: 28 | * 29 | * 输入: nums = [5,7,7,8,8,10], target = 6 30 | * 输出: [-1,-1] 31 | * 32 | */ 33 | 34 | // @lc code=start 35 | /** 36 | * @param {number[]} nums 37 | * @param {number} target 38 | * @return {number[]} 39 | */ 40 | const searchRange = function (nums, target) { 41 | const targetRange = [-1, -1] 42 | 43 | for (let i = 0; i < nums.length; i++) { 44 | if (nums[i] === target) { 45 | targetRange[0] = i 46 | break 47 | } 48 | } 49 | 50 | if (targetRange[0] === -1) { 51 | return targetRange 52 | } 53 | 54 | for (let j = nums.length - 1; j >= 0; j--) { 55 | if (nums[j] === target) { 56 | targetRange[1] = j 57 | break 58 | } 59 | } 60 | 61 | return targetRange 62 | } 63 | // @lc code=end 64 | -------------------------------------------------------------------------------- /344.反转字符串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=344 lang=javascript 3 | * 4 | * [344] 反转字符串 5 | * 6 | * https://leetcode-cn.com/problems/reverse-string/description/ 7 | * 8 | * algorithms 9 | * Easy (67.41%) 10 | * Likes: 166 11 | * Dislikes: 0 12 | * Total Accepted: 72.1K 13 | * Total Submissions: 106.7K 14 | * Testcase Example: '["h","e","l","l","o"]' 15 | * 16 | * 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。 17 | * 18 | * 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 19 | * 20 | * 你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。 21 | * 22 | * 23 | * 24 | * 示例 1: 25 | * 26 | * 输入:["h","e","l","l","o"] 27 | * 输出:["o","l","l","e","h"] 28 | * 29 | * 30 | * 示例 2: 31 | * 32 | * 输入:["H","a","n","n","a","h"] 33 | * 输出:["h","a","n","n","a","H"] 34 | * 35 | */ 36 | 37 | // js api 解法 38 | const reverseString1 = s => s.reverse() 39 | 40 | // 双指针解法 41 | const swap = (v, i, j) => { 42 | let temp = v[i] 43 | v[i] = v[j] 44 | v[j] = temp 45 | } 46 | 47 | const reverseString = s => { 48 | let left = 0 49 | let right = s.length - 1 50 | 51 | while (left < right) { 52 | swap(s, left, right) 53 | left++ 54 | right-- 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /35.搜索插入位置.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=35 lang=javascript 3 | * 4 | * [35] 搜索插入位置 5 | * 6 | * https://leetcode-cn.com/problems/search-insert-position/description/ 7 | * 8 | * algorithms 9 | * Easy (44.12%) 10 | * Likes: 320 11 | * Dislikes: 0 12 | * Total Accepted: 72.9K 13 | * Total Submissions: 164.7K 14 | * Testcase Example: '[1,3,5,6]\n5' 15 | * 16 | * 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 17 | * 18 | * 你可以假设数组中无重复元素。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: [1,3,5,6], 5 23 | * 输出: 2 24 | * 25 | * 26 | * 示例 2: 27 | * 28 | * 输入: [1,3,5,6], 2 29 | * 输出: 1 30 | * 31 | * 32 | * 示例 3: 33 | * 34 | * 输入: [1,3,5,6], 7 35 | * 输出: 4 36 | * 37 | * 38 | * 示例 4: 39 | * 40 | * 输入: [1,3,5,6], 0 41 | * 输出: 0 42 | * 43 | * 44 | */ 45 | /** 46 | * @param {number[]} nums 47 | * @param {number} target 48 | * @return {number} 49 | */ 50 | const searchInsert = (nums, target) => { 51 | return binarySearch(target, nums, 0, nums.length - 1) 52 | } 53 | 54 | const binarySearch = (data, arr, start, end) => { 55 | if (start > end) { 56 | return start 57 | } 58 | 59 | const mid = Math.floor(start + ((end - start) >> 1)) 60 | 61 | if (data === arr[mid]) { 62 | return mid 63 | } else if (data < arr[mid]) { 64 | return binarySearch(data, arr, start, mid - 1) 65 | } else { 66 | return binarySearch(data, arr, mid + 1, end) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /350.两个数组的交集-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=350 lang=javascript 3 | * 4 | * [350] 两个数组的交集 II 5 | * 6 | * https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/description/ 7 | * 8 | * algorithms 9 | * Easy (43.59%) 10 | * Likes: 185 11 | * Dislikes: 0 12 | * Total Accepted: 47K 13 | * Total Submissions: 106.3K 14 | * Testcase Example: '[1,2,2,1]\n[2,2]' 15 | * 16 | * 给定两个数组,编写一个函数来计算它们的交集。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: nums1 = [1,2,2,1], nums2 = [2,2] 21 | * 输出: [2,2] 22 | * 23 | * 24 | * 示例 2: 25 | * 26 | * 输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4] 27 | * 输出: [4,9] 28 | * 29 | * 说明: 30 | * 31 | * 32 | * 输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。 33 | * 我们可以不考虑输出结果的顺序。 34 | * 35 | * 36 | * 进阶: 37 | * 38 | * 39 | * 如果给定的数组已经排好序呢?你将如何优化你的算法? 40 | * 如果 nums1 的大小比 nums2 小很多,哪种方法更优? 41 | * 如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办? 42 | * 43 | * 44 | */ 45 | /** 46 | * @param {number[]} nums1 47 | * @param {number[]} nums2 48 | * @return {number[]} 49 | */ 50 | const intersect = function(nums1, nums2) { 51 | const map = new Map() 52 | 53 | for (const n of nums1) { 54 | if (map.has(n)) { 55 | map.set(n, map.get(n) + 1) 56 | } else { 57 | map.set(n, 1) 58 | } 59 | } 60 | 61 | const result = [] 62 | 63 | for (const n of nums2) { 64 | if (map.has(n) && map.get(n) > 0) { 65 | result.push(n) 66 | map.set(n, map.get(n) - 1) 67 | } 68 | } 69 | 70 | return result 71 | } 72 | -------------------------------------------------------------------------------- /371.两整数之和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=371 lang=javascript 3 | * 4 | * [371] 两整数之和 5 | * 6 | * https://leetcode-cn.com/problems/sum-of-two-integers/description/ 7 | * 8 | * algorithms 9 | * Easy (51.68%) 10 | * Likes: 147 11 | * Dislikes: 0 12 | * Total Accepted: 15.9K 13 | * Total Submissions: 30.6K 14 | * Testcase Example: '1\n2' 15 | * 16 | * 不使用运算符 + 和 - ​​​​​​​,计算两整数 ​​​​​​​a 、b ​​​​​​​之和。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: a = 1, b = 2 21 | * 输出: 3 22 | * 23 | * 24 | * 示例 2: 25 | * 26 | * 输入: a = -2, b = 3 27 | * 输出: 1 28 | * 29 | */ 30 | /** 31 | * @param {number} a 32 | * @param {number} b 33 | * @return {number} 34 | */ 35 | var getSum = function(a, b) { 36 | let carry 37 | 38 | while (b) { 39 | // 记录 a+b 的进位,直到进位为0是退出 40 | carry = (a & b) << 1 41 | 42 | //结果相加 43 | a ^= b 44 | 45 | // 循环 46 | b = carry 47 | } 48 | 49 | return a 50 | } 51 | -------------------------------------------------------------------------------- /374.猜数字大小.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=374 lang=javascript 3 | * 4 | * [374] 猜数字大小 5 | * 6 | * https://leetcode-cn.com/problems/guess-number-higher-or-lower/description/ 7 | * 8 | * algorithms 9 | * Easy (41.46%) 10 | * Likes: 54 11 | * Dislikes: 0 12 | * Total Accepted: 18K 13 | * Total Submissions: 41.7K 14 | * Testcase Example: '10\n6' 15 | * 16 | * 我们正在玩一个猜数字游戏。 游戏规则如下: 17 | * 我从 1 到 n 选择一个数字。 你需要猜我选择了哪个数字。 18 | * 每次你猜错了,我会告诉你这个数字是大了还是小了。 19 | * 你调用一个预先定义好的接口 guess(int num),它会返回 3 个可能的结果(-1,1 或 0): 20 | * 21 | * -1 : 我的数字比较小 22 | * ⁠1 : 我的数字比较大 23 | * ⁠0 : 恭喜!你猜对了! 24 | * 25 | * 26 | * 示例 : 27 | * 28 | * 输入: n = 10, pick = 6 29 | * 输出: 6 30 | * 31 | */ 32 | 33 | // @lc code=start 34 | 35 | /** 36 | * Forward declaration of guess API. 37 | * @param {number} num your guess 38 | * @return -1 if num is lower than the guess number 39 | * 1 if num is higher than the guess number 40 | * otherwise return 0 41 | * var guess = function(num) {} 42 | */ 43 | 44 | /** 45 | * @param {number} n 46 | * @return {number} 47 | */ 48 | const guessNumber = function(n) { 49 | let left = 1 50 | let right = n 51 | 52 | while (left <= right) { 53 | let mid = left + Math.floor((right - left) / 2) 54 | let res = guess(mid) 55 | 56 | if (res === 0) { 57 | return mid 58 | } else if (res < 0) { 59 | right = mid - 1 60 | } else { 61 | left = mid + 1 62 | } 63 | } 64 | 65 | return -1 66 | } 67 | // @lc code=end 68 | -------------------------------------------------------------------------------- /38.报数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=38 lang=javascript 3 | * 4 | * [38] 报数 5 | * 6 | * https://leetcode-cn.com/problems/count-and-say/description/ 7 | * 8 | * algorithms 9 | * Easy (52.04%) 10 | * Likes: 319 11 | * Dislikes: 0 12 | * Total Accepted: 50.5K 13 | * Total Submissions: 95.8K 14 | * Testcase Example: '1' 15 | * 16 | * 报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下: 17 | * 18 | * 1. 1 19 | * 2. 11 20 | * 3. 21 21 | * 4. 1211 22 | * 5. 111221 23 | * 24 | * 25 | * 1 被读作  "one 1"  ("一个一") , 即 11。 26 | * 11 被读作 "two 1s" ("两个一"), 即 21。 27 | * 21 被读作 "one 2",  "one 1" ("一个二" ,  "一个一") , 即 1211。 28 | * 29 | * 给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。 30 | * 31 | * 注意:整数顺序将表示为一个字符串。 32 | * 33 | * 34 | * 35 | * 示例 1: 36 | * 37 | * 输入: 1 38 | * 输出: "1" 39 | * 40 | * 41 | * 示例 2: 42 | * 43 | * 输入: 4 44 | * 输出: "1211" 45 | * 46 | * 47 | */ 48 | /** 49 | * @param {number} n 50 | * @return {string} 51 | */ 52 | const countAndSay = n => { 53 | let str = '1' 54 | 55 | for (let i = 1; i < n; i++) { 56 | let strArray = str.split('') 57 | 58 | str = '' 59 | 60 | let count = 1 61 | 62 | for (let j = 0; j < strArray.length; j++) { 63 | if (strArray[j] !== strArray[j + 1]) { 64 | str += count + strArray[j] 65 | count = 1 66 | } else { 67 | count++ 68 | } 69 | } 70 | } 71 | 72 | return str 73 | } 74 | -------------------------------------------------------------------------------- /387.字符串中的第一个唯一字符.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=387 lang=javascript 3 | * 4 | * [387] 字符串中的第一个唯一字符 5 | * 6 | * https://leetcode-cn.com/problems/first-unique-character-in-a-string/description/ 7 | * 8 | * algorithms 9 | * Easy (40.01%) 10 | * Likes: 147 11 | * Dislikes: 0 12 | * Total Accepted: 43.5K 13 | * Total Submissions: 106.9K 14 | * Testcase Example: '"leetcode"' 15 | * 16 | * 给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。 17 | * 18 | * 案例: 19 | * 20 | * 21 | * s = "leetcode" 22 | * 返回 0. 23 | * 24 | * s = "loveleetcode", 25 | * 返回 2. 26 | * 27 | * 28 | * 29 | * 30 | * 注意事项:您可以假定该字符串只包含小写字母。 31 | * 32 | */ 33 | /** 34 | * @param {string} s 35 | * @return {number} 36 | */ 37 | const firstUniqChar = s => { 38 | const hash = {} 39 | let minIndex = null 40 | let i = 0 41 | 42 | while (i < s.length) { 43 | if (hash[s[i]] || hash[s[i]] === 0) { 44 | hash[s[i]]++ 45 | } else { 46 | hash[s[i]] = 0 47 | } 48 | 49 | i++ 50 | } 51 | 52 | while (i-- > 0) { 53 | if (!hash[s[i]]) { 54 | minIndex = i 55 | } 56 | } 57 | 58 | if (minIndex === null) { 59 | return -1 60 | } 61 | 62 | return minIndex 63 | } 64 | -------------------------------------------------------------------------------- /4.median-of-two-sorted-arrays.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=4 lang=javascript 3 | * 4 | * [4] Median of Two Sorted Arrays 5 | */ 6 | /** 7 | * @param {number[]} nums1 8 | * @param {number[]} nums2 9 | * @return {number} 10 | */ 11 | const findMedianSortedArrays = (nums1, nums2) => { 12 | if (nums1.length > nums2.length) return findMedianSortedArrays(nums2, nums1) 13 | 14 | const x = nums1.length, 15 | y = nums2.length 16 | let lo = 0, 17 | hi = x 18 | 19 | while (lo <= hi) { 20 | let partitionX = ((lo + hi) / 2) | 0, 21 | partitionY = ((x + y + 1) / 2 - partitionX) | 0 22 | 23 | let maxLeftX = partitionX === 0 ? -Infinity : nums1[partitionX - 1] 24 | let minRightX = partitionX === x ? Infinity : nums1[partitionX] 25 | 26 | let maxLeftY = partitionY === 0 ? -Infinity : nums2[partitionY - 1] 27 | let minRightY = partitionY === y ? Infinity : nums2[partitionY] 28 | 29 | if (maxLeftX <= minRightY && maxLeftY <= minRightX) { 30 | if ((x + y) & 1) return Math.max(maxLeftX, maxLeftY) 31 | return (Math.max(maxLeftX, maxLeftY) + Math.min(minRightX, minRightY)) / 2 32 | } else if (maxLeftX > minRightY) { 33 | hi = partitionX - 1 34 | } else { 35 | lo = partitionX + 1 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /4.寻找两个有序数组的中位数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=4 lang=javascript 3 | * 4 | * [4] 寻找两个有序数组的中位数 5 | * 6 | * https://leetcode-cn.com/problems/median-of-two-sorted-arrays/description/ 7 | * 8 | * algorithms 9 | * Hard (35.87%) 10 | * Likes: 1433 11 | * Dislikes: 0 12 | * Total Accepted: 83.1K 13 | * Total Submissions: 231.7K 14 | * Testcase Example: '[1,3]\n[2]' 15 | * 16 | * 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。 17 | * 18 | * 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。 19 | * 20 | * 你可以假设 nums1 和 nums2 不会同时为空。 21 | * 22 | * 示例 1: 23 | * 24 | * nums1 = [1, 3] 25 | * nums2 = [2] 26 | * 27 | * 则中位数是 2.0 28 | * 29 | * 30 | * 示例 2: 31 | * 32 | * nums1 = [1, 2] 33 | * nums2 = [3, 4] 34 | * 35 | * 则中位数是 (2 + 3)/2 = 2.5 36 | * 37 | * 38 | */ 39 | /** 40 | * @param {number[]} nums1 41 | * @param {number[]} nums2 42 | * @return {number} 43 | */ 44 | const findMedianSortedArrays = (nums1, nums2) => { 45 | const arr = [...nums1, ...nums2].sort((a, b) => a - b) 46 | const { length } = arr 47 | 48 | return length % 2 49 | ? arr[Math.floor(length / 2)] 50 | : (arr[length / 2] + arr[length / 2 - 1]) / 2 51 | } 52 | -------------------------------------------------------------------------------- /41.缺失的第一个正数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=41 lang=javascript 3 | * 4 | * [41] 缺失的第一个正数 5 | * 6 | * https://leetcode-cn.com/problems/first-missing-positive/description/ 7 | * 8 | * algorithms 9 | * Hard (36.79%) 10 | * Likes: 295 11 | * Dislikes: 0 12 | * Total Accepted: 26.5K 13 | * Total Submissions: 71.8K 14 | * Testcase Example: '[1,2,0]' 15 | * 16 | * 给定一个未排序的整数数组,找出其中没有出现的最小的正整数。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: [1,2,0] 21 | * 输出: 3 22 | * 23 | * 24 | * 示例 2: 25 | * 26 | * 输入: [3,4,-1,1] 27 | * 输出: 2 28 | * 29 | * 30 | * 示例 3: 31 | * 32 | * 输入: [7,8,9,11,12] 33 | * 输出: 1 34 | * 35 | * 36 | * 说明: 37 | * 38 | * 你的算法的时间复杂度应为O(n),并且只能使用常数级别的空间。 39 | * 40 | */ 41 | 42 | // @lc code=start 43 | /** 44 | * @param {number[]} nums 45 | * @return {number} 46 | */ 47 | const firstMissingPositive = nums => { 48 | for (let i = 1, set = new Set(nums); true; i++) { 49 | if (!set.has(i)) { 50 | return i 51 | } 52 | } 53 | } // @lc code=end 54 | -------------------------------------------------------------------------------- /412.fizz-buzz.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=412 lang=javascript 3 | * 4 | * [412] Fizz Buzz 5 | * 6 | * https://leetcode-cn.com/problems/fizz-buzz/description/ 7 | * 8 | * algorithms 9 | * Easy (60.82%) 10 | * Likes: 34 11 | * Dislikes: 0 12 | * Total Accepted: 19.6K 13 | * Total Submissions: 32.1K 14 | * Testcase Example: '1' 15 | * 16 | * 写一个程序,输出从 1 到 n 数字的字符串表示。 17 | * 18 | * 1. 如果 n 是3的倍数,输出“Fizz”; 19 | * 20 | * 2. 如果 n 是5的倍数,输出“Buzz”; 21 | * 22 | * 3.如果 n 同时是3和5的倍数,输出 “FizzBuzz”。 23 | * 24 | * 示例: 25 | * 26 | * n = 15, 27 | * 28 | * 返回: 29 | * [ 30 | * ⁠ "1", 31 | * ⁠ "2", 32 | * ⁠ "Fizz", 33 | * ⁠ "4", 34 | * ⁠ "Buzz", 35 | * ⁠ "Fizz", 36 | * ⁠ "7", 37 | * ⁠ "8", 38 | * ⁠ "Fizz", 39 | * ⁠ "Buzz", 40 | * ⁠ "11", 41 | * ⁠ "Fizz", 42 | * ⁠ "13", 43 | * ⁠ "14", 44 | * ⁠ "FizzBuzz" 45 | * ] 46 | * 47 | * 48 | */ 49 | /** 50 | * @param {number} n 51 | * @return {string[]} 52 | */ 53 | const fizzBuzz = n => { 54 | return new Array(n) 55 | .fill(0) 56 | .map((a, i) => (++i % 3 ? '' : 'Fizz') + (i % 5 ? '' : 'Buzz') || '' + i) 57 | } 58 | -------------------------------------------------------------------------------- /415.字符串相加.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=415 lang=javascript 3 | * 4 | * [415] 字符串相加 5 | * 6 | * https://leetcode-cn.com/problems/add-strings/description/ 7 | * 8 | * algorithms 9 | * Easy (48.35%) 10 | * Likes: 115 11 | * Dislikes: 0 12 | * Total Accepted: 18.2K 13 | * Total Submissions: 37.6K 14 | * Testcase Example: '"0"\n"0"' 15 | * 16 | * 给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。 17 | * 18 | * 注意: 19 | * 20 | * 21 | * num1 和num2 的长度都小于 5100. 22 | * num1 和num2 都只包含数字 0-9. 23 | * num1 和num2 都不包含任何前导零。 24 | * 你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式。 25 | * 26 | * 27 | */ 28 | 29 | // @lc code=start 30 | /** 31 | * @param {string} num1 32 | * @param {string} num2 33 | * @return {string} 34 | */ 35 | const addStrings = function(num1, num2) { 36 | let i = num1.length - 1 37 | let j = num2.length - 1 38 | let carry = 0 39 | let sum = '' 40 | 41 | for (; i >= 0 || j >= 0 || carry > 0; i--, j--) { 42 | const digit1 = i < 0 ? 0 : num1.charAt(i) - '0' 43 | const digit2 = j < 0 ? 0 : num2.charAt(j) - '0' 44 | 45 | const digitsSum = digit1 + digit2 + carry 46 | 47 | sum = `${digitsSum % 10}${sum}` 48 | carry = Math.floor(digitsSum / 10) 49 | } 50 | 51 | return sum 52 | } 53 | // @lc code=end 54 | -------------------------------------------------------------------------------- /43.字符串相乘.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=43 lang=javascript 3 | * 4 | * [43] 字符串相乘 5 | */ 6 | /** 7 | * @param {string} num1 8 | * @param {string} num2 9 | * @return {string} 10 | */ 11 | // TODO: 待实现 12 | const multiply = (num1, num2) => { 13 | return (BigInt(num1) * BigInt(num2)).toString() 14 | } 15 | -------------------------------------------------------------------------------- /430.扁平化多级双向链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=430 lang=javascript 3 | * 4 | * [430] 扁平化多级双向链表 5 | * 6 | * https://leetcode-cn.com/problems/flatten-a-multilevel-doubly-linked-list/description/ 7 | * 8 | * algorithms 9 | * Medium (42.69%) 10 | * Likes: 51 11 | * Dislikes: 0 12 | * Total Accepted: 4.6K 13 | * Total Submissions: 10.6K 14 | * Testcase Example: '{"$id":"1","child":null,"next":{"$id":"2","child":null,"next":{"$id":"3","child":{"$id":"7","child":null,"next":{"$id":"8","child":{"$id":"11","child":null,"next":{"$id":"12","child":null,"next":null,"prev":{"$ref":"11"},"val":12},"prev":null,"val":11},"next":{"$id":"9","child":null,"next":{"$id":"10","child":null,"next":null,"prev":{"$ref":"9"},"val":10},"prev":{"$ref":"8"},"val":9},"prev":{"$ref":"7"},"val":8},"prev":null,"val":7},"next":{"$id":"4","child":null,"next":{"$id":"5","child":null,"next":{"$id":"6","child":null,"next":null,"prev":{"$ref":"5"},"val":6},"prev":{"$ref":"4"},"val":5},"prev":{"$ref":"3"},"val":4},"prev":{"$ref":"2"},"val":3},"prev":{"$ref":"1"},"val":2},"prev":null,"val":1}' 15 | * 16 | * 17 | * 您将获得一个双向链表,除了下一个和前一个指针之外,它还有一个子指针,可能指向单独的双向链表。这些子列表可能有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示。 18 | * 19 | * 扁平化列表,使所有结点出现在单级双链表中。您将获得列表第一级的头部。 20 | * 21 | * 22 | * 23 | * 示例: 24 | * 25 | * 输入: 26 | * ⁠1---2---3---4---5---6--NULL 27 | * ⁠ | 28 | * ⁠ 7---8---9---10--NULL 29 | * ⁠ | 30 | * ⁠ 11--12--NULL 31 | * 32 | * 输出: 33 | * 1-2-3-7-8-11-12-9-10-4-5-6-NULL 34 | * 35 | * 36 | * 37 | * 38 | * 以上示例的说明: 39 | * 40 | * 给出以下多级双向链表: 41 | * 42 | * 43 | * 44 | * 45 | * 46 | * 我们应该返回如下所示的扁平双向链表: 47 | * 48 | * 49 | * 50 | */ 51 | 52 | // @lc code=start 53 | /** 54 | * // Definition for a Node. 55 | * function Node(val,prev,next,child) { 56 | * this.val = val; 57 | * this.prev = prev; 58 | * this.next = next; 59 | * this.child = child; 60 | * }; 61 | */ 62 | // TODO: 63 | /** 64 | * @param {Node} head 65 | * @return {Node} 66 | */ 67 | const flatten = function (head) { 68 | const arr = [] 69 | const helper = node => { 70 | if (!node) return 71 | arr.push(node) 72 | helper(node.child) 73 | helper(node.next) 74 | } 75 | 76 | helper(head) 77 | 78 | for (let i = 0; i < arr.length; i++) { 79 | arr[i].prev = arr[i - 1] || null 80 | arr[i].next = arr[i + 1] || null 81 | arr[i].child = null 82 | } 83 | 84 | return arr[0] || null 85 | } 86 | // @lc code=end 87 | -------------------------------------------------------------------------------- /450.删除二叉搜索树中的节点.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=450 lang=javascript 3 | * 4 | * [450] 删除二叉搜索树中的节点 5 | * 6 | * https://leetcode-cn.com/problems/delete-node-in-a-bst/description/ 7 | * 8 | * algorithms 9 | * Medium (39.37%) 10 | * Likes: 160 11 | * Dislikes: 0 12 | * Total Accepted: 10.8K 13 | * Total Submissions: 27.3K 14 | * Testcase Example: '[5,3,6,2,4,null,7]\n3' 15 | * 16 | * 给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 17 | * 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。 18 | * 19 | * 一般来说,删除节点可分为两个步骤: 20 | * 21 | * 22 | * 首先找到需要删除的节点; 23 | * 如果找到了,删除它。 24 | * 25 | * 26 | * 说明: 要求算法时间复杂度为 O(h),h 为树的高度。 27 | * 28 | * 示例: 29 | * 30 | * 31 | * root = [5,3,6,2,4,null,7] 32 | * key = 3 33 | * 34 | * ⁠ 5 35 | * ⁠ / \ 36 | * ⁠ 3 6 37 | * ⁠/ \ \ 38 | * 2 4 7 39 | * 40 | * 给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。 41 | * 42 | * 一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。 43 | * 44 | * ⁠ 5 45 | * ⁠ / \ 46 | * ⁠ 4 6 47 | * ⁠/ \ 48 | * 2 7 49 | * 50 | * 另一个正确答案是 [5,2,6,null,4,null,7]。 51 | * 52 | * ⁠ 5 53 | * ⁠ / \ 54 | * ⁠ 2 6 55 | * ⁠ \ \ 56 | * ⁠ 4 7 57 | * 58 | * 59 | */ 60 | 61 | // @lc code=start 62 | /** 63 | * Definition for a binary tree node. 64 | * function TreeNode(val) { 65 | * this.val = val; 66 | * this.left = this.right = null; 67 | * } 68 | */ 69 | 70 | const successor = node => { 71 | node = node.right 72 | while (node.left) { 73 | node = node.left 74 | } 75 | return node.val 76 | } 77 | const predecessor = node => { 78 | node = node.left 79 | while (node.right) { 80 | node = node.right 81 | } 82 | return node.val 83 | } 84 | /** 85 | * @param {TreeNode} root 86 | * @param {number} key 87 | * @return {TreeNode} 88 | */ 89 | const deleteNode = function (root, key) { 90 | if (!root) { 91 | return null 92 | } 93 | if (root.val < key) { 94 | root.right = deleteNode(root.right, key) 95 | } else if (root.val > key) { 96 | root.left = deleteNode(root.left, key) 97 | } else { 98 | if (root.left) { 99 | root.val = predecessor(root) 100 | root.left = deleteNode(root.left, root.val) 101 | } else if (root.right) { 102 | root.val = successor(root) 103 | root.right = deleteNode(root.right, root.val) 104 | } else { 105 | root = null 106 | } 107 | } 108 | return root 109 | } 110 | // @lc code=end 111 | -------------------------------------------------------------------------------- /46.全排列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=46 lang=javascript 3 | * 4 | * [46] 全排列 5 | * 6 | * https://leetcode-cn.com/problems/permutations/description/ 7 | * 8 | * algorithms 9 | * Medium (71.53%) 10 | * Likes: 397 11 | * Dislikes: 0 12 | * Total Accepted: 48.8K 13 | * Total Submissions: 67.8K 14 | * Testcase Example: '[1,2,3]' 15 | * 16 | * 给定一个没有重复数字的序列,返回其所有可能的全排列。 17 | * 18 | * 示例: 19 | * 20 | * 输入: [1,2,3] 21 | * 输出: 22 | * [ 23 | * ⁠ [1,2,3], 24 | * ⁠ [1,3,2], 25 | * ⁠ [2,1,3], 26 | * ⁠ [2,3,1], 27 | * ⁠ [3,1,2], 28 | * ⁠ [3,2,1] 29 | * ] 30 | * 31 | */ 32 | 33 | // @lc code=start 34 | 35 | const backtrack = (result, tempList, nums) => { 36 | if (tempList.length === nums.length) { 37 | return result.push([...tempList]) 38 | } 39 | 40 | for (let i = 0; i < nums.length; i++) { 41 | if (tempList.includes(nums[i])) { 42 | continue 43 | } 44 | 45 | tempList.push(nums[i]) 46 | backtrack(result, tempList, nums) 47 | tempList.pop() 48 | } 49 | } 50 | 51 | /** 52 | * @param {number[]} nums 53 | * @return {number[][]} 54 | */ 55 | const permute = nums => { 56 | const result = [] 57 | 58 | backtrack(result, [], nums) 59 | 60 | return result 61 | } 62 | // @lc code=end 63 | -------------------------------------------------------------------------------- /485.最大连续-1-的个数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=485 lang=javascript 3 | * 4 | * [485] 最大连续1的个数 5 | * 6 | * https://leetcode-cn.com/problems/max-consecutive-ones/description/ 7 | * 8 | * algorithms 9 | * Easy (54.87%) 10 | * Likes: 70 11 | * Dislikes: 0 12 | * Total Accepted: 23.4K 13 | * Total Submissions: 42.6K 14 | * Testcase Example: '[1,0,1,1,0,1]' 15 | * 16 | * 给定一个二进制数组, 计算其中最大连续1的个数。 17 | * 18 | * 示例 1: 19 | * 20 | * 21 | * 输入: [1,1,0,1,1,1] 22 | * 输出: 3 23 | * 解释: 开头的两位和最后的三位都是连续1,所以最大连续1的个数是 3. 24 | * 25 | * 26 | * 注意: 27 | * 28 | * 29 | * 输入的数组只包含 0 和1。 30 | * 输入数组的长度是正整数,且不超过 10,000。 31 | * 32 | * 33 | */ 34 | 35 | // @lc code=start 36 | /** 37 | * @param {number[]} nums 38 | * @return {number} 39 | */ 40 | const findMaxConsecutiveOnes = function (nums) { 41 | let curr = 0 42 | let max = 0 43 | 44 | for (let k = 0; k < nums.length; k++) { 45 | if (nums[k] === 1) { 46 | max = Math.max(max, ++curr) 47 | } else { 48 | curr = 0 49 | } 50 | } 51 | 52 | return max 53 | } 54 | // @lc code=end 55 | -------------------------------------------------------------------------------- /498.对角线遍历.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=498 lang=javascript 3 | * 4 | * [498] 对角线遍历 5 | * 6 | * https://leetcode-cn.com/problems/diagonal-traverse/description/ 7 | * 8 | * algorithms 9 | * Medium (39.19%) 10 | * Likes: 65 11 | * Dislikes: 0 12 | * Total Accepted: 9K 13 | * Total Submissions: 23K 14 | * Testcase Example: '[[1,2,3],[4,5,6],[7,8,9]]' 15 | * 16 | * 给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。 17 | * 18 | * 19 | * 20 | * 示例: 21 | * 22 | * 输入: 23 | * [ 24 | * ⁠[ 1, 2, 3 ], 25 | * ⁠[ 4, 5, 6 ], 26 | * ⁠[ 7, 8, 9 ] 27 | * ] 28 | * 29 | * 输出: [1,2,4,7,5,3,6,8,9] 30 | * 31 | * 解释: 32 | * 33 | * 34 | * 35 | * 36 | * 37 | * 说明: 38 | * 39 | * 40 | * 给定矩阵中的元素总数不会超过 100000 。 41 | * 42 | * 43 | */ 44 | 45 | // @lc code=start 46 | /** 47 | * @param {number[][]} matrix 48 | * @return {number[]} 49 | */ 50 | const findDiagonalOrder = function (matrix) { 51 | if (matrix.length < 1 || matrix[0].length < 1) { 52 | return [] 53 | } 54 | 55 | let i = 0 56 | let j = 0 57 | let m = matrix.length 58 | let n = matrix[0].length 59 | 60 | let res = [] 61 | 62 | for (let k = 0; k < m * n; k++) { 63 | res.push(matrix[i][j]) 64 | 65 | if ((i - j) % 2 === 0) { 66 | if (j === n - 1) { 67 | i++ 68 | } else if (i === 0) { 69 | j++ 70 | } else { 71 | i-- 72 | j++ 73 | } 74 | } else { 75 | if (i === m - 1) { 76 | j++ 77 | } else if (j === 0) { 78 | i++ 79 | } else { 80 | i++ 81 | j-- 82 | } 83 | } 84 | } 85 | 86 | return res 87 | } 88 | // @lc code=end 89 | -------------------------------------------------------------------------------- /5.最长回文子串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=5 lang=javascript 3 | * 4 | * [5] 最长回文子串 5 | * 6 | * https://leetcode-cn.com/problems/longest-palindromic-substring/description/ 7 | * 8 | * algorithms 9 | * Medium (26.69%) 10 | * Likes: 1201 11 | * Dislikes: 0 12 | * Total Accepted: 97.5K 13 | * Total Submissions: 363.4K 14 | * Testcase Example: '"babad"' 15 | * 16 | * 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: "babad" 21 | * 输出: "bab" 22 | * 注意: "aba" 也是一个有效答案。 23 | * 24 | * 25 | * 示例 2: 26 | * 27 | * 输入: "cbbd" 28 | * 输出: "bb" 29 | * 30 | * 31 | */ 32 | /** 33 | * @param {string} s 34 | * @return {string} 35 | */ 36 | const longestPalindrome = s => { 37 | if (!s || s.length === 0) { 38 | return '' 39 | } 40 | 41 | let res = s[0] 42 | const dp = [] 43 | 44 | for (let i = s.length - 1; i >= 0; i--) { 45 | dp[i] = [] 46 | 47 | for (let j = i; j < s.length; j++) { 48 | if (j - i === 0) { 49 | dp[i][j] = true 50 | } else if (j - i === 1 && s[i] === s[j]) { 51 | dp[i][j] = true 52 | } else if (s[i] === s[j] && dp[i + 1][j - 1]) { 53 | dp[i][j] = true 54 | } 55 | 56 | if (dp[i][j] && j - i + 1 > res.length) { 57 | res = s.slice(i, j + 1) 58 | } 59 | } 60 | } 61 | 62 | return res 63 | } 64 | -------------------------------------------------------------------------------- /50.pow-x-n.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=50 lang=javascript 3 | * 4 | * [50] Pow(x, n) 5 | * 6 | * https://leetcode-cn.com/problems/powx-n/description/ 7 | * 8 | * algorithms 9 | * Medium (33.49%) 10 | * Likes: 280 11 | * Dislikes: 0 12 | * Total Accepted: 59.5K 13 | * Total Submissions: 174.1K 14 | * Testcase Example: '2.00000\n10' 15 | * 16 | * 实现 pow(x, n) ,即计算 x 的 n 次幂函数。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: 2.00000, 10 21 | * 输出: 1024.00000 22 | * 23 | * 24 | * 示例 2: 25 | * 26 | * 输入: 2.10000, 3 27 | * 输出: 9.26100 28 | * 29 | * 30 | * 示例 3: 31 | * 32 | * 输入: 2.00000, -2 33 | * 输出: 0.25000 34 | * 解释: 2^-2 = 1/2^2 = 1/4 = 0.25 35 | * 36 | * 说明: 37 | * 38 | * 39 | * -100.0 < x < 100.0 40 | * n 是 32 位有符号整数,其数值范围是 [−2^31, 2^31 − 1] 。 41 | * 42 | * 43 | */ 44 | 45 | // @lc code=start 46 | // TODO: 47 | /** 48 | * @param {number} x 49 | * @param {number} n 50 | * @return {number} 51 | */ 52 | const myPow = function (x, n) { 53 | if (n === 0) return 1 54 | 55 | let pow = Math.abs(n) 56 | 57 | let result = 58 | pow % 2 === 0 ? myPow(x * x, pow / 2) : myPow(x * x, (pow - 1) / 2) * x 59 | 60 | return n < 0 ? 1 / result : result 61 | } 62 | // @lc code=end 63 | -------------------------------------------------------------------------------- /51.n皇后.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=51 lang=javascript 3 | * 4 | * [51] N皇后 5 | * 6 | * https://leetcode-cn.com/problems/n-queens/description/ 7 | * 8 | * algorithms 9 | * Hard (66.87%) 10 | * Likes: 274 11 | * Dislikes: 0 12 | * Total Accepted: 19.7K 13 | * Total Submissions: 29.5K 14 | * Testcase Example: '4' 15 | * 16 | * n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。 17 | * 18 | * 19 | * 20 | * 上图为 8 皇后问题的一种解法。 21 | * 22 | * 给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。 23 | * 24 | * 每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。 25 | * 26 | * 示例: 27 | * 28 | * 输入: 4 29 | * 输出: [ 30 | * ⁠[".Q..", // 解法 1 31 | * ⁠ "...Q", 32 | * ⁠ "Q...", 33 | * ⁠ "..Q."], 34 | * 35 | * ⁠["..Q.", // 解法 2 36 | * ⁠ "Q...", 37 | * ⁠ "...Q", 38 | * ⁠ ".Q.."] 39 | * ] 40 | * 解释: 4 皇后问题存在两个不同的解法。 41 | * 42 | * 43 | */ 44 | 45 | // @lc code=start 46 | /** 47 | * @param {number} n 48 | * @return {string[][]} 49 | */ 50 | const solveNQueens = function (n) { 51 | const res = [] 52 | 53 | backtrack(res, n, [], 0) 54 | 55 | return res 56 | } 57 | 58 | function backtrack(res, n, board = [], r = 0) { 59 | if (r === n) { 60 | res.push(board.map(c => '.'.repeat(c) + 'Q' + '.'.repeat(n - c - 1))) 61 | return 62 | } 63 | for (let c = 0; c < n; c++) { 64 | if ( 65 | !board.some((bc, br) => { 66 | return bc === c || bc === c + r - br || bc === c - r + br 67 | }) 68 | ) { 69 | board.push(c) 70 | backtrack(res, n, board, r + 1) 71 | board.pop() 72 | } 73 | } 74 | } 75 | // @lc code=end 76 | -------------------------------------------------------------------------------- /53.最大子序和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=53 lang=javascript 3 | * 4 | * [53] 最大子序和 5 | * 6 | * https://leetcode-cn.com/problems/maximum-subarray/description/ 7 | * 8 | * algorithms 9 | * Easy (46.95%) 10 | * Likes: 1148 11 | * Dislikes: 0 12 | * Total Accepted: 85.5K 13 | * Total Submissions: 181.8K 14 | * Testcase Example: '[-2,1,-3,4,-1,2,1,-5,4]' 15 | * 16 | * 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 17 | * 18 | * 示例: 19 | * 20 | * 输入: [-2,1,-3,4,-1,2,1,-5,4], 21 | * 输出: 6 22 | * 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 23 | * 24 | * 25 | * 进阶: 26 | * 27 | * 如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。 28 | * 29 | */ 30 | /** 31 | * 思路 32 | * 33 | * 1. 动态规划的是首先对数组进行遍历,当前最大连续子序列和为 sum,结果为 ans 34 | * 2. 如果 sum > 0,则说明 sum 对结果有增益效果,则 sum 保留并加上当前遍历数字 35 | * 3. 如果 sum <= 0,则说明 sum 对结果无增益效果,需要舍弃,则 sum 直接更新为当前遍历数字 36 | * 4. 每次比较 sum 和 ans的大小,将最大值置为ans,遍历结束返回结果 37 | * 38 | * 时间复杂度 O(n) 39 | */ 40 | /** 41 | * @param {number[]} nums 42 | * @return {number} 43 | */ 44 | const maxSubArray = (nums = []) => { 45 | let ans = nums[0] 46 | let sum = 0 47 | 48 | for (const item of nums) { 49 | if (sum > 0) { 50 | sum += item 51 | } else { 52 | sum = item 53 | } 54 | 55 | ans = Math.max(sum, ans) 56 | } 57 | 58 | return ans 59 | } 60 | -------------------------------------------------------------------------------- /54.螺旋矩阵.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=54 lang=javascript 3 | * 4 | * [54] 螺旋矩阵 5 | * 6 | * https://leetcode-cn.com/problems/spiral-matrix/description/ 7 | * 8 | * algorithms 9 | * Medium (37.01%) 10 | * Likes: 219 11 | * Dislikes: 0 12 | * Total Accepted: 25.5K 13 | * Total Submissions: 68.5K 14 | * Testcase Example: '[[1,2,3],[4,5,6],[7,8,9]]' 15 | * 16 | * 给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: 21 | * [ 22 | * ⁠[ 1, 2, 3 ], 23 | * ⁠[ 4, 5, 6 ], 24 | * ⁠[ 7, 8, 9 ] 25 | * ] 26 | * 输出: [1,2,3,6,9,8,7,4,5] 27 | * 28 | * 29 | * 示例 2: 30 | * 31 | * 输入: 32 | * [ 33 | * ⁠ [1, 2, 3, 4], 34 | * ⁠ [5, 6, 7, 8], 35 | * ⁠ [9,10,11,12] 36 | * ] 37 | * 输出: [1,2,3,4,8,12,11,10,9,5,6,7] 38 | * 39 | * 40 | */ 41 | 42 | // @lc code=start 43 | /** 44 | * @param {number[][]} matrix 45 | * @return {number[]} 46 | */ 47 | 48 | // TODO: 49 | const spiralOrder = function (matrix) { 50 | if (!matrix.length) { 51 | return [] 52 | } 53 | 54 | const res = [] 55 | const dirs = [ 56 | [0, 1], 57 | [1, 0], 58 | [0, -1], 59 | [-1, 0], 60 | ] 61 | const range = [matrix[0].length, matrix.length - 1] 62 | 63 | let d = 0 64 | let r = 0 65 | let c = -1 66 | 67 | while (range[d % 2] > 0) { 68 | for (let i = 0; i < range[d % 2]; i++) { 69 | r += dirs[d][0] 70 | c += dirs[d][1] 71 | res.push(matrix[r][c]) 72 | } 73 | 74 | range[d % 2]-- 75 | d = (d + 1) % 4 76 | } 77 | 78 | return res 79 | } 80 | // @lc code=end 81 | -------------------------------------------------------------------------------- /557.反转字符串中的单词-iii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=557 lang=javascript 3 | * 4 | * [557] 反转字符串中的单词 III 5 | * 6 | * https://leetcode-cn.com/problems/reverse-words-in-a-string-iii/description/ 7 | * 8 | * algorithms 9 | * Easy (67.21%) 10 | * Likes: 117 11 | * Dislikes: 0 12 | * Total Accepted: 26.8K 13 | * Total Submissions: 39.8K 14 | * Testcase Example: `"Let's take LeetCode contest"` 15 | * 16 | * 给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。 17 | * 18 | * 示例 1: 19 | * 20 | * 21 | * 输入: "Let's take LeetCode contest" 22 | * 输出: "s'teL ekat edoCteeL tsetnoc" 23 | * 24 | * 25 | * 注意:在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格。 26 | * 27 | */ 28 | /** 29 | * @param {string} s 30 | * @return {string} 31 | */ 32 | const reverseWords = s => 33 | s 34 | .split(' ') 35 | .map(word => word.split('').reverse().join('')) 36 | .join(' ') 37 | -------------------------------------------------------------------------------- /561.数组拆分-i.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=561 lang=javascript 3 | * 4 | * [561] 数组拆分 I 5 | * 6 | * https://leetcode-cn.com/problems/array-partition-i/description/ 7 | * 8 | * algorithms 9 | * Easy (68.33%) 10 | * Likes: 125 11 | * Dislikes: 0 12 | * Total Accepted: 24.8K 13 | * Total Submissions: 36.1K 14 | * Testcase Example: '[1,4,3,2]' 15 | * 16 | * 给定长度为 2n 的数组, 你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), ..., (an, bn) ,使得从1 到 17 | * n 的 min(ai, bi) 总和最大。 18 | * 19 | * 示例 1: 20 | * 21 | * 22 | * 输入: [1,4,3,2] 23 | * 24 | * 输出: 4 25 | * 解释: n 等于 2, 最大总和为 4 = min(1, 2) + min(3, 4). 26 | * 27 | * 28 | * 提示: 29 | * 30 | * 31 | * n 是正整数,范围在 [1, 10000]. 32 | * 数组中的元素范围在 [-10000, 10000]. 33 | * 34 | * 35 | */ 36 | 37 | // @lc code=start 38 | /** 39 | * @param {number[]} nums 40 | * @return {number} 41 | */ 42 | const arrayPairSum = function (nums) { 43 | return nums 44 | .sort((a, b) => a - b) 45 | .filter((x, index) => index % 2 === 0) 46 | .reduce((a, b) => a + b) 47 | } 48 | // @lc code=end 49 | -------------------------------------------------------------------------------- /59.螺旋矩阵-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=59 lang=javascript 3 | * 4 | * [59] 螺旋矩阵 II 5 | * 6 | * https://leetcode-cn.com/problems/spiral-matrix-ii/description/ 7 | * 8 | * algorithms 9 | * Medium (74.45%) 10 | * Likes: 120 11 | * Dislikes: 0 12 | * Total Accepted: 16.7K 13 | * Total Submissions: 22.3K 14 | * Testcase Example: '3' 15 | * 16 | * 给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。 17 | * 18 | * 示例: 19 | * 20 | * 输入: 3 21 | * 输出: 22 | * [ 23 | * ⁠[ 1, 2, 3 ], 24 | * ⁠[ 8, 9, 4 ], 25 | * ⁠[ 7, 6, 5 ] 26 | * ] 27 | * 28 | */ 29 | 30 | // @lc code=start 31 | /** 32 | * @param {number} n 33 | * @return {number[][]} 34 | */ 35 | TODO: var generateMatrix = function (n) { 36 | if (n == 0) { 37 | return [] 38 | } 39 | 40 | if (n == 1) { 41 | return [[1]] 42 | } 43 | 44 | let result = [] 45 | let num = 1 46 | 47 | for (let i = 0; i < n; i++) { 48 | result.push([]) 49 | } 50 | 51 | let rowStart = 0 52 | let rowEnd = n - 1 53 | let colStart = 0 54 | let colEnd = n - 1 55 | 56 | while (rowStart <= rowEnd && colStart <= colEnd) { 57 | // to right 58 | for (let i = colStart; i <= colEnd; i++) { 59 | result[rowStart][i] = num 60 | num++ 61 | } 62 | rowStart++ 63 | 64 | // downwards 65 | for (let i = rowStart; i <= rowEnd; i++) { 66 | result[i][colEnd] = num 67 | num++ 68 | } 69 | colEnd-- 70 | 71 | // to left 72 | for (let i = colEnd; i >= colStart; i--) { 73 | result[rowEnd][i] = num 74 | num++ 75 | } 76 | rowEnd-- 77 | 78 | // upwards 79 | for (let i = rowEnd; i >= rowStart; i--) { 80 | result[i][colStart] = num 81 | num++ 82 | } 83 | colStart++ 84 | } 85 | return result 86 | } 87 | // @lc code=end 88 | -------------------------------------------------------------------------------- /599.两个列表的最小索引总和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=599 lang=javascript 3 | * 4 | * [599] 两个列表的最小索引总和 5 | * 6 | * https://leetcode-cn.com/problems/minimum-index-sum-of-two-lists/description/ 7 | * 8 | * algorithms 9 | * Easy (48.80%) 10 | * Likes: 48 11 | * Dislikes: 0 12 | * Total Accepted: 8.7K 13 | * Total Submissions: 17.7K 14 | * Testcase Example: '["Shogun","Tapioca Express","Burger King","KFC"]\n["Piatti","The Grill at Torrey Pines","Hungry Hunter Steakhouse","Shogun"]' 15 | * 16 | * 假设Andy和Doris想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示。 17 | * 18 | * 你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅。 如果答案不止一个,则输出所有答案并且不考虑顺序。 你可以假设总是存在一个答案。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: 23 | * ["Shogun", "Tapioca Express", "Burger King", "KFC"] 24 | * ["Piatti", "The Grill at Torrey Pines", "Hungry Hunter Steakhouse", 25 | * "Shogun"] 26 | * 输出: ["Shogun"] 27 | * 解释: 他们唯一共同喜爱的餐厅是“Shogun”。 28 | * 29 | * 30 | * 示例 2: 31 | * 32 | * 输入: 33 | * ["Shogun", "Tapioca Express", "Burger King", "KFC"] 34 | * ["KFC", "Shogun", "Burger King"] 35 | * 输出: ["Shogun"] 36 | * 解释: 他们共同喜爱且具有最小索引和的餐厅是“Shogun”,它有最小的索引和1(0+1)。 37 | * 38 | * 39 | * 提示: 40 | * 41 | * 42 | * 两个列表的长度范围都在 [1, 1000]内。 43 | * 两个列表中的字符串的长度将在[1,30]的范围内。 44 | * 下标从0开始,到列表的长度减1。 45 | * 两个列表都没有重复的元素。 46 | * 47 | * 48 | */ 49 | 50 | // @lc code=start 51 | /** 52 | * @param {string[]} list1 53 | * @param {string[]} list2 54 | * @return {string[]} 55 | */ 56 | const findRestaurant = function (list1, list2) { 57 | let out = [] 58 | let obj = new Map() 59 | 60 | list2.forEach((v, i) => obj.set(v, i)) 61 | 62 | let i = 0 63 | let min = Infinity 64 | 65 | while (i < list1.length) { 66 | if (obj.has(list1[i])) { 67 | let sum = i + obj.get(list1[i]) 68 | 69 | if (min === sum) { 70 | out.push(list1[i]) 71 | } else if (sum < min) { 72 | out = [list1[i]] 73 | min = sum 74 | } 75 | } 76 | 77 | i++ 78 | } 79 | 80 | return out 81 | } 82 | // @lc code=end 83 | -------------------------------------------------------------------------------- /6.z-字形变换.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=6 lang=javascript 3 | * 4 | * [6] Z 字形变换 5 | * 6 | * https://leetcode-cn.com/problems/zigzag-conversion/description/ 7 | * 8 | * algorithms 9 | * Medium (45.35%) 10 | * Likes: 427 11 | * Dislikes: 0 12 | * Total Accepted: 67.9K 13 | * Total Submissions: 149.6K 14 | * Testcase Example: '"PAYPALISHIRING"\n3' 15 | * 16 | * 将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。 17 | * 18 | * 比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下: 19 | * 20 | * L C I R 21 | * E T O E S I I G 22 | * E D H N 23 | * 24 | * 25 | * 之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。 26 | * 27 | * 请你实现这个将字符串进行指定行数变换的函数: 28 | * 29 | * string convert(string s, int numRows); 30 | * 31 | * 示例 1: 32 | * 33 | * 输入: s = "LEETCODEISHIRING", numRows = 3 34 | * 输出: "LCIRETOESIIGEDHN" 35 | * 36 | * 37 | * 示例 2: 38 | * 39 | * 输入: s = "LEETCODEISHIRING", numRows = 4 40 | * 输出: "LDREOEIIECIHNTSG" 41 | * 解释: 42 | * 43 | * L D R 44 | * E O E I I 45 | * E C I H N 46 | * T S G 47 | * 48 | */ 49 | 50 | // @lc code=start 51 | /** 52 | * @param {string} s 53 | * @param {number} numRows 54 | * @return {string} 55 | */ 56 | TODO: const convert = (s, numRows) => { 57 | // return original string if can't zigzag 58 | if (numRows === 1 || s.length < numRows) { 59 | return s 60 | } 61 | 62 | let rows = [] 63 | let converted = '' 64 | let reverse = false 65 | let count = 0 66 | 67 | // prepare rows 68 | for (let i = 0; i < numRows; i++) { 69 | rows[i] = [] 70 | } 71 | 72 | // reverse the push flow when reaching turning points 73 | for (let i = 0; i < s.length; i++) { 74 | rows[count].push(s[i]) 75 | reverse ? count-- : count++ 76 | 77 | if (count === numRows - 1 || count === 0) { 78 | reverse = !reverse 79 | } 80 | } 81 | // put together converted string 82 | return rows.reduce((converted, cur) => converted + cur.join(''), '') 83 | } 84 | // @lc code=end 85 | -------------------------------------------------------------------------------- /60.第k个排列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=60 lang=javascript 3 | * 4 | * [60] 第k个排列 5 | * 6 | * https://leetcode-cn.com/problems/permutation-sequence/description/ 7 | * 8 | * algorithms 9 | * Medium (47.57%) 10 | * Likes: 153 11 | * Dislikes: 0 12 | * Total Accepted: 19.7K 13 | * Total Submissions: 41.2K 14 | * Testcase Example: '3\n3' 15 | * 16 | * 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。 17 | * 18 | * 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: 19 | * 20 | * 21 | * "123" 22 | * "132" 23 | * "213" 24 | * "231" 25 | * "312" 26 | * "321" 27 | * 28 | * 29 | * 给定 n 和 k,返回第 k 个排列。 30 | * 31 | * 说明: 32 | * 33 | * 34 | * 给定 n 的范围是 [1, 9]。 35 | * 给定 k 的范围是[1,  n!]。 36 | * 37 | * 38 | * 示例 1: 39 | * 40 | * 输入: n = 3, k = 3 41 | * 输出: "213" 42 | * 43 | * 44 | * 示例 2: 45 | * 46 | * 输入: n = 4, k = 9 47 | * 输出: "2314" 48 | * 49 | * 50 | */ 51 | // TODO: 52 | // @lc code=start 53 | const getFactorial = function (n) { 54 | if (n === 1) { 55 | return n 56 | } else if (n > 1) { 57 | return n * getFactorial(n - 1) 58 | } 59 | } 60 | 61 | /** 62 | * @param {number} n 63 | * @param {number} k 64 | * @return {string} 65 | */ 66 | const getPermutation = function (n, k) { 67 | let res = [] 68 | let arr = [] 69 | 70 | for (let i = 1; i <= n; i++) { 71 | arr.push(i) 72 | } 73 | 74 | let n2 = n 75 | 76 | for (let i = 0; i < n2; i++) { 77 | let nf = getFactorial(n - 1) 78 | let x = Math.ceil(k / nf) - 1 79 | 80 | res.push(arr.splice(x, 1)[0]) 81 | 82 | k -= x * nf 83 | n = n - 1 84 | } 85 | 86 | return res.join('') 87 | } 88 | // @lc code=end 89 | -------------------------------------------------------------------------------- /61.旋转链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=61 lang=javascript 3 | * 4 | * [61] 旋转链表 5 | * 6 | * https://leetcode-cn.com/problems/rotate-list/description/ 7 | * 8 | * algorithms 9 | * Medium (39.00%) 10 | * Likes: 150 11 | * Dislikes: 0 12 | * Total Accepted: 27.1K 13 | * Total Submissions: 69.4K 14 | * Testcase Example: '[1,2,3,4,5]\n2' 15 | * 16 | * 给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: 1->2->3->4->5->NULL, k = 2 21 | * 输出: 4->5->1->2->3->NULL 22 | * 解释: 23 | * 向右旋转 1 步: 5->1->2->3->4->NULL 24 | * 向右旋转 2 步: 4->5->1->2->3->NULL 25 | * 26 | * 27 | * 示例 2: 28 | * 29 | * 输入: 0->1->2->NULL, k = 4 30 | * 输出: 2->0->1->NULL 31 | * 解释: 32 | * 向右旋转 1 步: 2->0->1->NULL 33 | * 向右旋转 2 步: 1->2->0->NULL 34 | * 向右旋转 3 步: 0->1->2->NULL 35 | * 向右旋转 4 步: 2->0->1->NULL 36 | * 37 | */ 38 | 39 | // @lc code=start 40 | /** 41 | * Definition for singly-linked list. 42 | * function ListNode(val) { 43 | * this.val = val; 44 | * this.next = null; 45 | * } 46 | */ 47 | /** 48 | * @param {ListNode} head 49 | * @param {number} k 50 | * @return {ListNode} 51 | */ 52 | const rotateRight = (head, k) => { 53 | let target = head, 54 | last = null, 55 | len = 1 56 | 57 | while (target && target.next) { 58 | target = target.next 59 | len++ 60 | } 61 | 62 | last = target 63 | target = head 64 | 65 | if (k % len === 0) { 66 | return head 67 | } 68 | 69 | let diff = len - (k % len) 70 | let pre = null 71 | 72 | while (target && diff--) { 73 | pre = target 74 | target = target.next 75 | } 76 | 77 | pre.next = null 78 | last.next = head 79 | 80 | return target 81 | } 82 | // @lc code=end 83 | -------------------------------------------------------------------------------- /617.合并二叉树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=617 lang=javascript 3 | * 4 | * [617] 合并二叉树 5 | * 6 | * https://leetcode-cn.com/problems/merge-two-binary-trees/description/ 7 | * 8 | * algorithms 9 | * Easy (72.53%) 10 | * Likes: 225 11 | * Dislikes: 0 12 | * Total Accepted: 19.4K 13 | * Total Submissions: 26.7K 14 | * Testcase Example: '[1,3,2,5]\n[2,1,3,null,4,null,7]' 15 | * 16 | * 给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。 17 | * 18 | * 你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 19 | * 的节点将直接作为新二叉树的节点。 20 | * 21 | * 示例 1: 22 | * 23 | * 24 | * 输入: 25 | * Tree 1 Tree 2 26 | * ⁠ 1 2 27 | * ⁠ / \ / \ 28 | * ⁠ 3 2 1 3 29 | * ⁠ / \ \ 30 | * ⁠ 5 4 7 31 | * 输出: 32 | * 合并后的树: 33 | * 3 34 | * / \ 35 | * 4 5 36 | * / \ \ 37 | * 5 4 7 38 | * 39 | * 40 | * 注意: 合并必须从两个树的根节点开始。 41 | * 42 | */ 43 | /** 44 | * Definition for a binary tree node. 45 | * function TreeNode(val) { 46 | * this.val = val; 47 | * this.left = this.right = null; 48 | * } 49 | */ 50 | /** 51 | * @param {TreeNode} t1 52 | * @param {TreeNode} t2 53 | * @return {TreeNode} 54 | */ 55 | const mergeTrees = (t1, t2) => { 56 | if (!t1 && !t2) { 57 | return null 58 | } 59 | 60 | const root = new TreeNode(((t1 && t1.val) || 0) + ((t2 && t2.val) || 0)) 61 | 62 | root.left = mergeTrees(t1 && t1.left, t2 && t2.left) 63 | root.right = mergeTrees(t1 && t1.right, t2 && t2.right) 64 | 65 | return root 66 | } 67 | -------------------------------------------------------------------------------- /62.不同路径.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=62 lang=javascript 3 | * 4 | * [62] 不同路径 5 | * 6 | * https://leetcode-cn.com/problems/unique-paths/description/ 7 | * 8 | * algorithms 9 | * Medium (55.94%) 10 | * Likes: 333 11 | * Dislikes: 0 12 | * Total Accepted: 42.4K 13 | * Total Submissions: 75K 14 | * Testcase Example: '3\n2' 15 | * 16 | * 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。 17 | * 18 | * 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。 19 | * 20 | * 问总共有多少条不同的路径? 21 | * 22 | * 23 | * 24 | * 例如,上图是一个7 x 3 的网格。有多少可能的路径? 25 | * 26 | * 说明:m 和 n 的值均不超过 100。 27 | * 28 | * 示例 1: 29 | * 30 | * 输入: m = 3, n = 2 31 | * 输出: 3 32 | * 解释: 33 | * 从左上角开始,总共有 3 条路径可以到达右下角。 34 | * 1. 向右 -> 向右 -> 向下 35 | * 2. 向右 -> 向下 -> 向右 36 | * 3. 向下 -> 向右 -> 向右 37 | * 38 | * 39 | * 示例 2: 40 | * 41 | * 输入: m = 7, n = 3 42 | * 输出: 28 43 | * 44 | */ 45 | 46 | // @lc code=start 47 | /** 48 | * @param {number} m 49 | * @param {number} n 50 | * @return {number} 51 | */ 52 | var uniquePaths = function (m, n) { 53 | const dp = [] 54 | 55 | for (let i = 0; i < m + 1; i++) { 56 | dp[i] = [] 57 | dp[i][0] = 0 58 | } 59 | 60 | for (let i = 0; i < n + 1; i++) { 61 | dp[0][i] = 0 62 | } 63 | 64 | for (let i = 1; i < m + 1; i++) { 65 | for (let j = 1; j < n + 1; j++) { 66 | dp[i][j] = j === 1 ? 1 : dp[i - 1][j] + dp[i][j - 1] // 转移方程 67 | } 68 | } 69 | 70 | return dp[m][n] 71 | } 72 | // @lc code=end 73 | -------------------------------------------------------------------------------- /622.设计循环队列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=622 lang=javascript 3 | * 4 | * [622] 设计循环队列 5 | * 6 | * https://leetcode-cn.com/problems/design-circular-queue/description/ 7 | * 8 | * algorithms 9 | * Medium (39.07%) 10 | * Likes: 66 11 | * Dislikes: 0 12 | * Total Accepted: 16K 13 | * Total Submissions: 40.5K 14 | * Testcase Example: '["MyCircularQueue","enQueue","enQueue","enQueue","enQueue","Rear","isFull","deQueue","enQueue","Rear"]\n[[3],[1],[2],[3],[4],[],[],[],[4],[]]' 15 | * 16 | * 设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 17 | * FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 18 | * 19 | * 20 | * 循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。 21 | * 22 | * 你的实现应该支持如下操作: 23 | * 24 | * 25 | * MyCircularQueue(k): 构造器,设置队列长度为 k 。 26 | * Front: 从队首获取元素。如果队列为空,返回 -1 。 27 | * Rear: 获取队尾元素。如果队列为空,返回 -1 。 28 | * enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。 29 | * deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。 30 | * isEmpty(): 检查循环队列是否为空。 31 | * isFull(): 检查循环队列是否已满。 32 | * 33 | * 34 | * 35 | * 36 | * 示例: 37 | * 38 | * MyCircularQueue circularQueue = new MycircularQueue(3); // 设置长度为 3 39 | * 40 | * circularQueue.enQueue(1);  // 返回 true 41 | * 42 | * circularQueue.enQueue(2);  // 返回 true 43 | * 44 | * circularQueue.enQueue(3);  // 返回 true 45 | * 46 | * circularQueue.enQueue(4);  // 返回 false,队列已满 47 | * 48 | * circularQueue.Rear();  // 返回 3 49 | * 50 | * circularQueue.isFull();  // 返回 true 51 | * 52 | * circularQueue.deQueue();  // 返回 true 53 | * 54 | * circularQueue.enQueue(4);  // 返回 true 55 | * 56 | * circularQueue.Rear();  // 返回 4 57 | * 58 | * 59 | * 60 | * 61 | * 提示: 62 | * 63 | * 64 | * 所有的值都在 0 至 1000 的范围内; 65 | * 操作数将在 1 至 1000 的范围内; 66 | * 请不要使用内置的队列库。 67 | * 68 | * 69 | */ 70 | 71 | // @lc code=start 72 | /** 73 | * Initialize your data structure here. Set the size of the queue to be k. 74 | * @param {number} k 75 | */ 76 | const MyCircularQueue = function (k) { 77 | this.storage = [] 78 | this.currentSize = 0 79 | this.maxSize = k 80 | this.front = 0 81 | this.rear = -1 82 | } 83 | 84 | MyCircularQueue.prototype.enQueue = function (value) { 85 | if (this.currentSize >= this.maxSize) { 86 | return false 87 | } 88 | 89 | this.rear = ++this.rear % this.maxSize 90 | this.storage[this.rear] = value 91 | this.currentSize++ 92 | 93 | return true 94 | } 95 | 96 | MyCircularQueue.prototype.deQueue = function () { 97 | if (this.currentSize === 0) { 98 | return false 99 | } 100 | 101 | this.front = ++this.front % this.maxSize 102 | this.currentSize-- 103 | 104 | return true 105 | } 106 | 107 | MyCircularQueue.prototype.Front = function () { 108 | return this.currentSize === 0 ? -1 : this.storage[this.front] 109 | } 110 | 111 | MyCircularQueue.prototype.Rear = function () { 112 | return this.currentSize === 0 ? -1 : this.storage[this.rear] 113 | } 114 | 115 | MyCircularQueue.prototype.isEmpty = function () { 116 | return this.currentSize === 0 117 | } 118 | 119 | MyCircularQueue.prototype.isFull = function () { 120 | return this.currentSize === this.maxSize 121 | } 122 | // @lc code=end 123 | -------------------------------------------------------------------------------- /658.找到-k-个最接近的元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=658 lang=javascript 3 | * 4 | * [658] 找到 K 个最接近的元素 5 | * 6 | * https://leetcode-cn.com/problems/find-k-closest-elements/description/ 7 | * 8 | * algorithms 9 | * Medium (41.74%) 10 | * Likes: 65 11 | * Dislikes: 0 12 | * Total Accepted: 7.1K 13 | * Total Submissions: 16.7K 14 | * Testcase Example: '[1,2,3,4,5]\n4\n3' 15 | * 16 | * 给定一个排序好的数组,两个整数 k 和 x,从数组中找到最靠近 x(两数之差最小)的 k 个数。返回的结果必须要是按升序排好的。如果有两个数与 x 17 | * 的差值一样,优先选择数值较小的那个数。 18 | * 19 | * 示例 1: 20 | * 21 | * 22 | * 输入: [1,2,3,4,5], k=4, x=3 23 | * 输出: [1,2,3,4] 24 | * 25 | * 26 | * 27 | * 28 | * 示例 2: 29 | * 30 | * 31 | * 输入: [1,2,3,4,5], k=4, x=-1 32 | * 输出: [1,2,3,4] 33 | * 34 | * 35 | * 36 | * 37 | * 说明: 38 | * 39 | * 40 | * k 的值为正数,且总是小于给定排序数组的长度。 41 | * 数组不为空,且长度不超过 10^4 42 | * 数组里的每个元素与 x 的绝对值不超过 10^4 43 | * 44 | * 45 | * 46 | * 47 | * 更新(2017/9/19): 48 | * 这个参数 arr 已经被改变为一个整数数组(而不是整数列表)。 请重新加载代码定义以获取最新更改。 49 | * 50 | */ 51 | 52 | // @lc code=start 53 | /** 54 | * @param {number[]} arr 55 | * @param {number} k 56 | * @param {number} x 57 | * @return {number[]} 58 | */ 59 | 60 | // TODO: 61 | const findClosestElements = function (arr, k, x) { 62 | arr = arr.sort((a, b) => a - b) 63 | } 64 | // @lc code=end 65 | -------------------------------------------------------------------------------- /66.加一.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=66 lang=javascript 3 | * 4 | * [66] 加一 5 | * 6 | * https://leetcode-cn.com/problems/plus-one/description/ 7 | * 8 | * algorithms 9 | * Easy (40.41%) 10 | * Likes: 352 11 | * Dislikes: 0 12 | * Total Accepted: 80.6K 13 | * Total Submissions: 196.4K 14 | * Testcase Example: '[1,2,3]' 15 | * 16 | * 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。 17 | * 18 | * 最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。 19 | * 20 | * 你可以假设除了整数 0 之外,这个整数不会以零开头。 21 | * 22 | * 示例 1: 23 | * 24 | * 输入: [1,2,3] 25 | * 输出: [1,2,4] 26 | * 解释: 输入数组表示数字 123。 27 | * 28 | * 29 | * 示例 2: 30 | * 31 | * 输入: [4,3,2,1] 32 | * 输出: [4,3,2,2] 33 | * 解释: 输入数组表示数字 4321。 34 | * 35 | * 36 | */ 37 | /** 38 | * @param {number[]} digits 39 | * @return {number[]} 40 | */ 41 | const plusOne = function (digits, index = digits.length - 1) { 42 | if (digits[index] === 9) { 43 | digits[index] = 0 44 | 45 | if (index <= 0) { 46 | return [1, ...digits] 47 | } else { 48 | return plusOne(digits, index - 1) 49 | } 50 | } 51 | 52 | digits[index]++ 53 | 54 | return digits 55 | } 56 | -------------------------------------------------------------------------------- /67.二进制求和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=67 lang=javascript 3 | * 4 | * [67] 二进制求和 5 | * 6 | * https://leetcode-cn.com/problems/add-binary/description/ 7 | * 8 | * algorithms 9 | * Easy (51.43%) 10 | * Likes: 272 11 | * Dislikes: 0 12 | * Total Accepted: 52K 13 | * Total Submissions: 100.9K 14 | * Testcase Example: '"11"\n"1"' 15 | * 16 | * 给定两个二进制字符串,返回他们的和(用二进制表示)。 17 | * 18 | * 输入为非空字符串且只包含数字 1 和 0。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: a = "11", b = "1" 23 | * 输出: "100" 24 | * 25 | * 示例 2: 26 | * 27 | * 输入: a = "1010", b = "1011" 28 | * 输出: "10101" 29 | * 30 | */ 31 | 32 | // @lc code=start 33 | /** 34 | * @param {string} a 35 | * @param {string} b 36 | * @return {string} 37 | */ 38 | const addBinary = function (a, b) { 39 | const aBin = `0b${a}` 40 | const bBin = `0b${b}` 41 | const sum = BigInt(aBin) + BigInt(bBin) 42 | return sum.toString(2) 43 | } 44 | // @lc code=end 45 | -------------------------------------------------------------------------------- /69.x-的平方根.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=69 lang=javascript 3 | * 4 | * [69] x 的平方根 5 | * 6 | * https://leetcode-cn.com/problems/sqrtx/description/ 7 | * 8 | * algorithms 9 | * Easy (36.73%) 10 | * Likes: 227 11 | * Dislikes: 0 12 | * Total Accepted: 58.7K 13 | * Total Submissions: 159.2K 14 | * Testcase Example: '4' 15 | * 16 | * 实现 int sqrt(int x) 函数。 17 | * 18 | * 计算并返回 x 的平方根,其中 x 是非负整数。 19 | * 20 | * 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。 21 | * 22 | * 示例 1: 23 | * 24 | * 输入: 4 25 | * 输出: 2 26 | * 27 | * 28 | * 示例 2: 29 | * 30 | * 输入: 8 31 | * 输出: 2 32 | * 说明: 8 的平方根是 2.82842..., 33 | * 由于返回类型是整数,小数部分将被舍去。 34 | * 35 | * 36 | */ 37 | /** 38 | * @param {number} x 39 | * @return {number} 40 | */ 41 | const mySqrt = x => { 42 | let left = 1 43 | let right = Math.floor(x / 2) + 1 44 | let mid 45 | 46 | while (left <= right) { 47 | mid = Math.floor((left + right) / 2) 48 | 49 | if (mid * mid > x) { 50 | right = mid - 1 51 | } else if (mid * mid < x) { 52 | left = mid + 1 53 | } else { 54 | return mid 55 | } 56 | } 57 | 58 | return right 59 | } 60 | -------------------------------------------------------------------------------- /7.整数反转.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=7 lang=javascript 3 | * 4 | * [7] 整数反转 5 | * 6 | * https://leetcode-cn.com/problems/reverse-integer/description/ 7 | * 8 | * algorithms 9 | * Easy (32.85%) 10 | * Likes: 1299 11 | * Dislikes: 0 12 | * Total Accepted: 178.4K 13 | * Total Submissions: 540.5K 14 | * Testcase Example: '123' 15 | * 16 | * 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: 123 21 | * 输出: 321 22 | * 23 | * 24 | * 示例 2: 25 | * 26 | * 输入: -123 27 | * 输出: -321 28 | * 29 | * 30 | * 示例 3: 31 | * 32 | * 输入: 120 33 | * 输出: 21 34 | * 35 | * 36 | * 注意: 37 | * 38 | * 假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31,  2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 39 | * 0。 40 | * 41 | */ 42 | /** 43 | * @param {number} x 44 | * @return {number} 45 | */ 46 | const reverse = x => { 47 | let str = x.toString().split('').reverse().join('') 48 | let num = parseInt(x < 0 ? `-${str}` : str) 49 | 50 | if (num > Math.pow(2, 31) - 1 || num < Math.pow(-2, 31)) { 51 | return 0 52 | } 53 | 54 | return num 55 | } 56 | -------------------------------------------------------------------------------- /70.爬楼梯.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=70 lang=javascript 3 | * 4 | * [70] 爬楼梯 5 | * 6 | * https://leetcode-cn.com/problems/climbing-stairs/description/ 7 | * 8 | * algorithms 9 | * Easy (46.51%) 10 | * Likes: 605 11 | * Dislikes: 0 12 | * Total Accepted: 73.7K 13 | * Total Submissions: 158.2K 14 | * Testcase Example: '2' 15 | * 16 | * 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 17 | * 18 | * 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 19 | * 20 | * 注意:给定 n 是一个正整数。 21 | * 22 | * 示例 1: 23 | * 24 | * 输入: 2 25 | * 输出: 2 26 | * 解释: 有两种方法可以爬到楼顶。 27 | * 1. 1 阶 + 1 阶 28 | * 2. 2 阶 29 | * 30 | * 示例 2: 31 | * 32 | * 输入: 3 33 | * 输出: 3 34 | * 解释: 有三种方法可以爬到楼顶。 35 | * 1. 1 阶 + 1 阶 + 1 阶 36 | * 2. 1 阶 + 2 阶 37 | * 3. 2 阶 + 1 阶 38 | * 39 | * 40 | */ 41 | /** 42 | * @param {number} n 43 | * @return {number} 44 | */ 45 | const climbStairs = (n, hash = {}) => { 46 | if (n <= 2) { 47 | return n 48 | } 49 | 50 | if (!hash[n]) { 51 | hash[n] = climbStairs(n - 1, hash) + climbStairs(n - 2, hash) 52 | } 53 | 54 | return hash[n] 55 | } 56 | 57 | // 动态规划 58 | const climbStairs2 = () => { 59 | if (n <= 2) { 60 | return n 61 | } 62 | 63 | let a = 1 64 | let b = 2 65 | let temp 66 | 67 | for (let i = 3; i <= n; i++) { 68 | temp = a + b 69 | a = b 70 | b = temp 71 | } 72 | 73 | return temp 74 | } 75 | 76 | // 尾递归 77 | const climbStairs3 = (n, a = 1, b = 2) => { 78 | if (n <= 1) { 79 | return a 80 | } 81 | 82 | return climbStairs(n - 1, b, a + b) 83 | } 84 | -------------------------------------------------------------------------------- /700.二叉搜索树中的搜索.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=700 lang=javascript 3 | * 4 | * [700] 二叉搜索树中的搜索 5 | * 6 | * https://leetcode-cn.com/problems/search-in-a-binary-search-tree/description/ 7 | * 8 | * algorithms 9 | * Easy (72.70%) 10 | * Likes: 53 11 | * Dislikes: 0 12 | * Total Accepted: 20.4K 13 | * Total Submissions: 28.1K 14 | * Testcase Example: '[4,2,7,1,3]\n2' 15 | * 16 | * 给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。 17 | * 18 | * 例如, 19 | * 20 | * 21 | * 给定二叉搜索树: 22 | * 23 | * ⁠ 4 24 | * ⁠ / \ 25 | * ⁠ 2 7 26 | * ⁠ / \ 27 | * ⁠ 1 3 28 | * 29 | * 和值: 2 30 | * 31 | * 32 | * 你应该返回如下子树: 33 | * 34 | * 35 | * ⁠ 2 36 | * ⁠ / \ 37 | * ⁠ 1 3 38 | * 39 | * 40 | * 在上述示例中,如果要找的值是 5,但因为没有节点值为 5,我们应该返回 NULL。 41 | * 42 | */ 43 | 44 | // @lc code=start 45 | /** 46 | * Definition for a binary tree node. 47 | * function TreeNode(val) { 48 | * this.val = val; 49 | * this.left = this.right = null; 50 | * } 51 | */ 52 | /** 53 | * @param {TreeNode} root 54 | * @param {number} val 55 | * @return {TreeNode} 56 | */ 57 | const searchBST = function (root, val) { 58 | if (root === null || val === root.val) { 59 | return root 60 | } 61 | 62 | return val < root.val ? searchBST(root.left, val) : searchBST(root.right, val) 63 | } 64 | // @lc code=end 65 | -------------------------------------------------------------------------------- /701.二叉搜索树中的插入操作.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=701 lang=javascript 3 | * 4 | * [701] 二叉搜索树中的插入操作 5 | * 6 | * https://leetcode-cn.com/problems/insert-into-a-binary-search-tree/description/ 7 | * 8 | * algorithms 9 | * Medium (73.46%) 10 | * Likes: 51 11 | * Dislikes: 0 12 | * Total Accepted: 9.5K 13 | * Total Submissions: 12.9K 14 | * Testcase Example: '[4,2,7,1,3]\n5' 15 | * 16 | * 给定二叉搜索树(BST)的根节点和要插入树中的值,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 保证原始二叉搜索树中不存在新值。 17 | * 18 | * 注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回任意有效的结果。 19 | * 20 | * 例如, 21 | * 22 | * 23 | * 给定二叉搜索树: 24 | * 25 | * ⁠ 4 26 | * ⁠ / \ 27 | * ⁠ 2 7 28 | * ⁠ / \ 29 | * ⁠ 1 3 30 | * 31 | * 和 插入的值: 5 32 | * 33 | * 34 | * 你可以返回这个二叉搜索树: 35 | * 36 | * 37 | * ⁠ 4 38 | * ⁠ / \ 39 | * ⁠ 2 7 40 | * ⁠ / \ / 41 | * ⁠ 1 3 5 42 | * 43 | * 44 | * 或者这个树也是有效的: 45 | * 46 | * 47 | * ⁠ 5 48 | * ⁠ / \ 49 | * ⁠ 2 7 50 | * ⁠ / \ 51 | * ⁠ 1 3 52 | * ⁠ \ 53 | * ⁠ 4 54 | * 55 | * 56 | */ 57 | 58 | // @lc code=start 59 | /** 60 | * Definition for a binary tree node. 61 | * function TreeNode(val) { 62 | * this.val = val; 63 | * this.left = this.right = null; 64 | * } 65 | */ 66 | /** 67 | * @param {TreeNode} root 68 | * @param {number} val 69 | * @return {TreeNode} 70 | */ 71 | const insertIntoBST = function (root, val) { 72 | if (root === null) { 73 | return new TreeNode(val) 74 | } 75 | 76 | if (val > root.val) { 77 | root.right = insertIntoBST(root.right, val) 78 | } else { 79 | root.left = insertIntoBST(root.left, val) 80 | } 81 | 82 | return root 83 | } 84 | // @lc code=end 85 | -------------------------------------------------------------------------------- /703.数据流中的第k大元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=703 lang=javascript 3 | * 4 | * [703] 数据流中的第K大元素 5 | * 6 | * https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/description/ 7 | * 8 | * algorithms 9 | * Easy (42.83%) 10 | * Likes: 109 11 | * Dislikes: 0 12 | * Total Accepted: 16.5K 13 | * Total Submissions: 38.5K 14 | * Testcase Example: '["KthLargest","add","add","add","add","add"]\n[[3,[4,5,8,2]],[3],[5],[10],[9],[4]]' 15 | * 16 | * 设计一个找到数据流中第K大元素的类(class)。注意是排序后的第K大元素,不是第K个不同的元素。 17 | * 18 | * 你的 KthLargest 类需要一个同时接收整数 k 和整数数组nums 的构造器,它包含数据流中的初始元素。每次调用 19 | * KthLargest.add,返回当前数据流中第K大的元素。 20 | * 21 | * 示例: 22 | * 23 | * 24 | * int k = 3; 25 | * int[] arr = [4,5,8,2]; 26 | * KthLargest kthLargest = new KthLargest(3, arr); 27 | * kthLargest.add(3);   // returns 4 28 | * kthLargest.add(5);   // returns 5 29 | * kthLargest.add(10);  // returns 5 30 | * kthLargest.add(9);   // returns 8 31 | * kthLargest.add(4);   // returns 8 32 | * 33 | * 34 | * 说明: 35 | * 你可以假设 nums 的长度≥ k-1 且k ≥ 1。 36 | * 37 | */ 38 | 39 | // TODO: 40 | // @lc code=start 41 | /** 42 | * @param {number} k 43 | * @param {number[]} nums 44 | */ 45 | var KthLargest = function (k, nums) {} 46 | 47 | /** 48 | * @param {number} val 49 | * @return {number} 50 | */ 51 | KthLargest.prototype.add = function (val) {} 52 | 53 | /** 54 | * Your KthLargest object will be instantiated and called as such: 55 | * var obj = new KthLargest(k, nums) 56 | * var param_1 = obj.add(val) 57 | */ 58 | class MinHeap {} 59 | // @lc code=end 60 | -------------------------------------------------------------------------------- /704.二分查找.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=704 lang=javascript 3 | * 4 | * [704] 二分查找 5 | * 6 | * https://leetcode-cn.com/problems/binary-search/description/ 7 | * 8 | * algorithms 9 | * Easy (51.33%) 10 | * Likes: 90 11 | * Dislikes: 0 12 | * Total Accepted: 23.8K 13 | * Total Submissions: 46.3K 14 | * Testcase Example: '[-1,0,3,5,9,12]\n9' 15 | * 16 | * 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 17 | * target,如果目标值存在返回下标,否则返回 -1。 18 | * 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: nums = [-1,0,3,5,9,12], target = 9 23 | * 输出: 4 24 | * 解释: 9 出现在 nums 中并且下标为 4 25 | * 26 | * 27 | * 示例 2: 28 | * 29 | * 输入: nums = [-1,0,3,5,9,12], target = 2 30 | * 输出: -1 31 | * 解释: 2 不存在 nums 中因此返回 -1 32 | * 33 | * 34 | * 35 | * 36 | * 提示: 37 | * 38 | * 39 | * 你可以假设 nums 中的所有元素是不重复的。 40 | * n 将在 [1, 10000]之间。 41 | * nums 的每个元素都将在 [-9999, 9999]之间。 42 | * 43 | * 44 | */ 45 | 46 | // @lc code=start 47 | /** 48 | * @param {number[]} nums 49 | * @param {number} target 50 | * @return {number} 51 | */ 52 | const search = function (nums, target) { 53 | let pivot 54 | let left = 0 55 | let right = nums.length 56 | 57 | while (left <= right) { 58 | pivot = Math.floor(((right - left) >> 1) + left) 59 | 60 | if (nums[pivot] === target) { 61 | return pivot 62 | } else if (target < nums[pivot]) { 63 | right = pivot - 1 64 | } else { 65 | left = pivot + 1 66 | } 67 | } 68 | 69 | return -1 70 | } 71 | // @lc code=end 72 | -------------------------------------------------------------------------------- /721.账户合并.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=721 lang=javascript 3 | * 4 | * [721] 账户合并 5 | * 6 | * https://leetcode-cn.com/problems/accounts-merge/description/ 7 | * 8 | * algorithms 9 | * Medium (29.37%) 10 | * Likes: 32 11 | * Dislikes: 0 12 | * Total Accepted: 1.1K 13 | * Total Submissions: 3.8K 14 | * Testcase Example: '[["John","johnsmith@mail.com","john_newyork@mail.com"],["John","johnsmith@mail.com","john00@mail.com"],["Mary","mary@mail.com"],["John","johnnybravo@mail.com"]]' 15 | * 16 | * 给定一个列表 accounts,每个元素 accounts[i] 是一个字符串列表,其中第一个元素 accounts[i][0] 是 名称 17 | * (name),其余元素是 emails 表示该帐户的邮箱地址。 18 | * 19 | * 20 | * 现在,我们想合并这些帐户。如果两个帐户都有一些共同的邮件地址,则两个帐户必定属于同一个人。请注意,即使两个帐户具有相同的名称,它们也可能属于不同的人,因为人们可能具有相同的名称。一个人最初可以拥有任意数量的帐户,但其所有帐户都具有相同的名称。 21 | * 22 | * 合并帐户后,按以下格式返回帐户:每个帐户的第一个元素是名称,其余元素是按顺序排列的邮箱地址。accounts 本身可以以任意顺序返回。 23 | * 24 | * 例子 1: 25 | * 26 | * 27 | * Input: 28 | * accounts = [["John", "johnsmith@mail.com", "john00@mail.com"], ["John", 29 | * "johnnybravo@mail.com"], ["John", "johnsmith@mail.com", 30 | * "john_newyork@mail.com"], ["Mary", "mary@mail.com"]] 31 | * Output: [["John", 'john00@mail.com', 'john_newyork@mail.com', 32 | * 'johnsmith@mail.com'], ["John", "johnnybravo@mail.com"], ["Mary", 33 | * "mary@mail.com"]] 34 | * Explanation: 35 | * ⁠ 第一个和第三个 John 是同一个人,因为他们有共同的电子邮件 "johnsmith@mail.com"。 36 | * ⁠ 第二个 John 和 Mary 是不同的人,因为他们的电子邮件地址没有被其他帐户使用。 37 | * ⁠ 38 | * 我们可以以任何顺序返回这些列表,例如答案[['Mary','mary@mail.com'],['John','johnnybravo@mail.com'], 39 | * ⁠ 40 | * ['John','john00@mail.com','john_newyork@mail.com','johnsmith@mail.com']]仍然会被接受。 41 | * 42 | * 43 | * 44 | * 注意: 45 | * 46 | * 47 | * accounts的长度将在[1,1000]的范围内。 48 | * accounts[i]的长度将在[1,10]的范围内。 49 | * accounts[i][j]的长度将在[1,30]的范围内。 50 | * 51 | * 52 | */ 53 | 54 | // @lc code=start 55 | /** 56 | * @param {string[][]} accounts 57 | * @return {string[][]} 58 | */ 59 | var accountsMerge = function (accounts) {} 60 | // @lc code=end 61 | -------------------------------------------------------------------------------- /724.寻找数组的中心索引.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=724 lang=javascript 3 | * 4 | * [724] 寻找数组的中心索引 5 | * 6 | * https://leetcode-cn.com/problems/find-pivot-index/description/ 7 | * 8 | * algorithms 9 | * Easy (35.59%) 10 | * Likes: 133 11 | * Dislikes: 0 12 | * Total Accepted: 22.2K 13 | * Total Submissions: 62.4K 14 | * Testcase Example: '[1,7,3,6,5,6]' 15 | * 16 | * 给定一个整数类型的数组 nums,请编写一个能够返回数组“中心索引”的方法。 17 | * 18 | * 我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和。 19 | * 20 | * 如果数组不存在中心索引,那么我们应该返回 -1。如果数组有多个中心索引,那么我们应该返回最靠近左边的那一个。 21 | * 22 | * 示例 1: 23 | * 24 | * 25 | * 输入: 26 | * nums = [1, 7, 3, 6, 5, 6] 27 | * 输出: 3 28 | * 解释: 29 | * 索引3 (nums[3] = 6) 的左侧数之和(1 + 7 + 3 = 11),与右侧数之和(5 + 6 = 11)相等。 30 | * 同时, 3 也是第一个符合要求的中心索引。 31 | * 32 | * 33 | * 示例 2: 34 | * 35 | * 36 | * 输入: 37 | * nums = [1, 2, 3] 38 | * 输出: -1 39 | * 解释: 40 | * 数组中不存在满足此条件的中心索引。 41 | * 42 | * 说明: 43 | * 44 | * 45 | * nums 的长度范围为 [0, 10000]。 46 | * 任何一个 nums[i] 将会是一个范围在 [-1000, 1000]的整数。 47 | * 48 | * 49 | */ 50 | 51 | // @lc code=start 52 | /** 53 | * @param {number[]} nums 54 | * @return {number} 55 | */ 56 | const pivotIndex = function (nums) { 57 | const sum = nums.reduce((prev, next) => prev + next, 0) 58 | 59 | let leftSum = 0 60 | 61 | for (let i = 0; i < nums.length; i++) { 62 | if (leftSum === sum - nums[i] - leftSum) { 63 | return i 64 | } 65 | 66 | leftSum += nums[i] 67 | } 68 | 69 | return -1 70 | } 71 | // @lc code=end 72 | -------------------------------------------------------------------------------- /747.至少是其他数字两倍的最大数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=747 lang=javascript 3 | * 4 | * [747] 至少是其他数字两倍的最大数 5 | * 6 | * https://leetcode-cn.com/problems/largest-number-at-least-twice-of-others/description/ 7 | * 8 | * algorithms 9 | * Easy (38.37%) 10 | * Likes: 45 11 | * Dislikes: 0 12 | * Total Accepted: 18.2K 13 | * Total Submissions: 47.4K 14 | * Testcase Example: '[0,0,0,1]' 15 | * 16 | * 在一个给定的数组nums中,总是存在一个最大元素 。 17 | * 18 | * 查找数组中的最大元素是否至少是数组中每个其他数字的两倍。 19 | * 20 | * 如果是,则返回最大元素的索引,否则返回-1。 21 | * 22 | * 示例 1: 23 | * 24 | * 输入: nums = [3, 6, 1, 0] 25 | * 输出: 1 26 | * 解释: 6是最大的整数, 对于数组中的其他整数, 27 | * 6大于数组中其他元素的两倍。6的索引是1, 所以我们返回1. 28 | * 29 | * 30 | * 31 | * 32 | * 示例 2: 33 | * 34 | * 输入: nums = [1, 2, 3, 4] 35 | * 输出: -1 36 | * 解释: 4没有超过3的两倍大, 所以我们返回 -1. 37 | * 38 | * 39 | * 40 | * 41 | * 提示: 42 | * 43 | * 44 | * nums 的长度范围在[1, 50]. 45 | * 每个 nums[i] 的整数范围在 [0, 100]. 46 | * 47 | * 48 | */ 49 | 50 | // @lc code=start 51 | /** 52 | * @param {number[]} nums 53 | * @return {number} 54 | */ 55 | const dominantIndex = function (nums) { 56 | let maxIndex = 0 57 | 58 | for (let i = 0; i < nums.length; i++) { 59 | if (nums[i] > nums[maxIndex]) { 60 | maxIndex = i 61 | } 62 | } 63 | 64 | for (let i = 0; i < nums.length; i++) { 65 | if (maxIndex !== i && nums[maxIndex] < 2 * nums[i]) { 66 | return -1 67 | } 68 | } 69 | 70 | return maxIndex 71 | } 72 | // @lc code=end 73 | -------------------------------------------------------------------------------- /75.颜色分类.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=75 lang=javascript 3 | * 4 | * [75] 颜色分类 5 | */ 6 | /** 7 | * @param {number[]} nums 8 | * @return {void} Do not return anything, modify nums in-place instead. 9 | */ 10 | const sortColors = nums => { 11 | let p0 = 0 12 | let p2 = nums.length - 1 13 | let curr = 0 14 | 15 | while (curr <= p2) { 16 | if (nums[curr] === 0) { 17 | ;[nums[p0], nums[curr]] = [nums[curr], nums[p0]] 18 | p0++ 19 | curr++ 20 | } else if (nums[curr] === 2) { 21 | ;[nums[p2], nums[curr]] = [nums[curr], nums[p2]] 22 | p2-- 23 | } else { 24 | curr++ 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /752.打开转盘锁.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=752 lang=javascript 3 | * 4 | * [752] 打开转盘锁 5 | * 6 | * https://leetcode-cn.com/problems/open-the-lock/description/ 7 | * 8 | * algorithms 9 | * Medium (48.01%) 10 | * Likes: 67 11 | * Dislikes: 0 12 | * Total Accepted: 7.2K 13 | * Total Submissions: 15K 14 | * Testcase Example: '["0201","0101","0102","1212","2002"]\n"0202"' 15 | * 16 | * 你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有10个数字: '0', '1', '2', '3', '4', '5', '6', '7', '8', 17 | * '9' 。每个拨轮可以自由旋转:例如把 '9' 变为  '0','0' 变为 '9' 。每次旋转都只能旋转一个拨轮的一位数字。 18 | * 19 | * 锁的初始数字为 '0000' ,一个代表四个拨轮的数字的字符串。 20 | * 21 | * 列表 deadends 包含了一组死亡数字,一旦拨轮的数字和列表里的任何一个元素相同,这个锁将会被永久锁定,无法再被旋转。 22 | * 23 | * 字符串 target 代表可以解锁的数字,你需要给出最小的旋转次数,如果无论如何不能解锁,返回 -1。 24 | * 25 | * 26 | * 27 | * 示例 1: 28 | * 29 | * 30 | * 输入:deadends = ["0201","0101","0102","1212","2002"], target = "0202" 31 | * 输出:6 32 | * 解释: 33 | * 可能的移动序列为 "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "0202"。 34 | * 注意 "0000" -> "0001" -> "0002" -> "0102" -> "0202" 这样的序列是不能解锁的, 35 | * 因为当拨动到 "0102" 时这个锁就会被锁定。 36 | * 37 | * 38 | * 示例 2: 39 | * 40 | * 41 | * 输入: deadends = ["8888"], target = "0009" 42 | * 输出:1 43 | * 解释: 44 | * 把最后一位反向旋转一次即可 "0000" -> "0009"。 45 | * 46 | * 47 | * 示例 3: 48 | * 49 | * 50 | * 输入: deadends = ["8887","8889","8878","8898","8788","8988","7888","9888"], 51 | * target = "8888" 52 | * 输出:-1 53 | * 解释: 54 | * 无法旋转到目标数字且不被锁定。 55 | * 56 | * 57 | * 示例 4: 58 | * 59 | * 60 | * 输入: deadends = ["0000"], target = "8888" 61 | * 输出:-1 62 | * 63 | * 64 | * 65 | * 66 | * 提示: 67 | * 68 | * 69 | * 死亡列表 deadends 的长度范围为 [1, 500]。 70 | * 目标数字 target 不会在 deadends 之中。 71 | * 每个 deadends 和 target 中的字符串的数字会在 10,000 个可能的情况 '0000' 到 '9999' 中产生。 72 | * 73 | * 74 | */ 75 | 76 | // @lc code=start 77 | /** 78 | * @param {string[]} deadends 79 | * @param {string} target 80 | * @return {number} 81 | */ 82 | var openLock = function (deadends, target) {} 83 | // @lc code=end 84 | -------------------------------------------------------------------------------- /78.子集.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=78 lang=javascript 3 | * 4 | * [78] 子集 5 | * 6 | * https://leetcode-cn.com/problems/subsets/description/ 7 | * 8 | * algorithms 9 | * Medium (74.73%) 10 | * Likes: 355 11 | * Dislikes: 0 12 | * Total Accepted: 38.5K 13 | * Total Submissions: 51.5K 14 | * Testcase Example: '[1,2,3]' 15 | * 16 | * 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。 17 | * 18 | * 说明:解集不能包含重复的子集。 19 | * 20 | * 示例: 21 | * 22 | * 输入: nums = [1,2,3] 23 | * 输出: 24 | * [ 25 | * ⁠ [3], 26 | * [1], 27 | * [2], 28 | * [1,2,3], 29 | * [1,3], 30 | * [2,3], 31 | * [1,2], 32 | * [] 33 | * ] 34 | * 35 | */ 36 | 37 | // @lc code=start 38 | 39 | const backtrack = (list, tempList, nums, start) => { 40 | list.push([...tempList]) 41 | 42 | for (let i = start; i < nums.length; i++) { 43 | tempList.push(nums[i]) 44 | backtrack(list, tempList, nums, i + 1) 45 | tempList.pop() 46 | } 47 | } 48 | 49 | const subsets = nums => { 50 | const list = [] 51 | backtrack(list, [], nums, 0) 52 | return list 53 | } 54 | // @lc code=end 55 | -------------------------------------------------------------------------------- /8.字符串转换整数-atoi.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=8 lang=javascript 3 | * 4 | * [8] 字符串转换整数 (atoi) 5 | */ 6 | /** 7 | * @param {string} str 8 | * @return {number} 9 | */ 10 | const myAtoi = str => { 11 | const result = str.trim().match(/^(-|\+)?\d+/g) 12 | 13 | return result 14 | ? Math.max( 15 | Math.min(Number(result[0]), Math.pow(2, 31) - 1), 16 | Math.pow(-2, 31) 17 | ) 18 | : 0 19 | } 20 | -------------------------------------------------------------------------------- /876.middle-of-the-linked-list.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode id=876 lang=javascript 3 | * 4 | * [876] Middle of the Linked List 5 | */ 6 | /** 7 | * Definition for singly-linked list. 8 | * function ListNode(val) { 9 | * this.val = val; 10 | * this.next = null; 11 | * } 12 | */ 13 | /** 14 | * @param {ListNode} head 15 | * @return {ListNode} 16 | */ 17 | const middleNode = head => { 18 | let slow = head 19 | let fast = head 20 | 21 | while (fast !== null && fast.next !== null) { 22 | slow = slow.next 23 | fast = fast.next.next 24 | } 25 | 26 | return slow 27 | } 28 | -------------------------------------------------------------------------------- /88.合并两个有序数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=88 lang=javascript 3 | * 4 | * [88] 合并两个有序数组 5 | * 6 | * https://leetcode-cn.com/problems/merge-sorted-array/description/ 7 | * 8 | * algorithms 9 | * Easy (45.06%) 10 | * Likes: 299 11 | * Dislikes: 0 12 | * Total Accepted: 63.9K 13 | * Total Submissions: 141.7K 14 | * Testcase Example: '[1,2,3,0,0,0]\n3\n[2,5,6]\n3' 15 | * 16 | * 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。 17 | * 18 | * 说明: 19 | * 20 | * 21 | * 初始化 nums1 和 nums2 的元素数量分别为 m 和 n。 22 | * 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。 23 | * 24 | * 25 | * 示例: 26 | * 27 | * 输入: 28 | * nums1 = [1,2,3,0,0,0], m = 3 29 | * nums2 = [2,5,6], n = 3 30 | * 31 | * 输出: [1,2,2,3,5,6] 32 | * 33 | */ 34 | /** 35 | * @param {number[]} nums1 36 | * @param {number} m 37 | * @param {number[]} nums2 38 | * @param {number} n 39 | * @return {void} Do not return anything, modify nums1 in-place instead. 40 | */ 41 | const merge = function (nums1, m, nums2, n) { 42 | let current = m + n - 1 43 | 44 | while (current >= 0) { 45 | if (n === 0) { 46 | return 47 | } 48 | 49 | if (nums1[m - 1] > nums2[n - 1]) { 50 | nums1[current--] = nums1[--m] 51 | } else { 52 | nums1[current--] = nums2[--n] 53 | } 54 | } 55 | } 56 | 57 | /** 58 | * 复杂度分析: 59 | * 60 | * 时间复杂度:O(M + N) 61 | * 空间复杂度:O(1) 62 | */ 63 | -------------------------------------------------------------------------------- /89.格雷编码.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=89 lang=javascript 3 | * 4 | * [89] 格雷编码 5 | * 6 | * https://leetcode-cn.com/problems/gray-code/description/ 7 | * 8 | * algorithms 9 | * Medium (65.87%) 10 | * Likes: 87 11 | * Dislikes: 0 12 | * Total Accepted: 11.9K 13 | * Total Submissions: 17.9K 14 | * Testcase Example: '2' 15 | * 16 | * 格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异。 17 | * 18 | * 给定一个代表编码总位数的非负整数 n,打印其格雷编码序列。格雷编码序列必须以 0 开头。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: 2 23 | * 输出: [0,1,3,2] 24 | * 解释: 25 | * 00 - 0 26 | * 01 - 1 27 | * 11 - 3 28 | * 10 - 2 29 | * 30 | * 对于给定的 n,其格雷编码序列并不唯一。 31 | * 例如,[0,2,3,1] 也是一个有效的格雷编码序列。 32 | * 33 | * 00 - 0 34 | * 10 - 2 35 | * 11 - 3 36 | * 01 - 1 37 | * 38 | * 示例 2: 39 | * 40 | * 输入: 0 41 | * 输出: [0] 42 | * 解释: 我们定义格雷编码序列必须以 0 开头。 43 | * 给定编码总位数为 n 的格雷编码序列,其长度为 2^n。当 n = 0 时,长度为 2^0 = 1。 44 | * 因此,当 n = 0 时,其格雷编码序列为 [0]。 45 | * 46 | * 47 | */ 48 | 49 | // @lc code=start 50 | /** 51 | * @param {number} n 52 | * @return {number[]} 53 | */ 54 | // TODO: 55 | var grayCode = function (n) { 56 | if (n === 0) { 57 | return [0] 58 | } 59 | 60 | const res = grayCode(n - 1) 61 | const mask = 1 << (n - 1) 62 | 63 | for (let i = res.length - 1; i >= 0; i--) { 64 | res.push(res[i] | mask) 65 | } 66 | 67 | return res 68 | } 69 | // @lc code=end 70 | -------------------------------------------------------------------------------- /9.回文数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=9 lang=javascript 3 | * 4 | * [9] 回文数 5 | * 6 | * https://leetcode-cn.com/problems/palindrome-number/description/ 7 | * 8 | * algorithms 9 | * Easy (56.50%) 10 | * Likes: 724 11 | * Dislikes: 0 12 | * Total Accepted: 157.9K 13 | * Total Submissions: 279.3K 14 | * Testcase Example: '121' 15 | * 16 | * 判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: 121 21 | * 输出: true 22 | * 23 | * 24 | * 示例 2: 25 | * 26 | * 输入: -121 27 | * 输出: false 28 | * 解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。 29 | * 30 | * 31 | * 示例 3: 32 | * 33 | * 输入: 10 34 | * 输出: false 35 | * 解释: 从右向左读, 为 01 。因此它不是一个回文数。 36 | * 37 | * 38 | * 进阶: 39 | * 40 | * 你能不将整数转为字符串来解决这个问题吗? 41 | * 42 | */ 43 | /** 44 | * @param {number} x 45 | * @return {boolean} 46 | */ 47 | const isPalindrome = x => String(x) === String(x).split('').reverse().join('') 48 | -------------------------------------------------------------------------------- /94.二叉树的中序遍历.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=94 lang=javascript 3 | * 4 | * [94] 二叉树的中序遍历 5 | * 6 | * https://leetcode-cn.com/problems/binary-tree-inorder-traversal/description/ 7 | * 8 | * algorithms 9 | * Medium (68.70%) 10 | * Likes: 325 11 | * Dislikes: 0 12 | * Total Accepted: 80K 13 | * Total Submissions: 115.9K 14 | * Testcase Example: '[1,null,2,3]' 15 | * 16 | * 给定一个二叉树,返回它的中序 遍历。 17 | * 18 | * 示例: 19 | * 20 | * 输入: [1,null,2,3] 21 | * ⁠ 1 22 | * ⁠ \ 23 | * ⁠ 2 24 | * ⁠ / 25 | * ⁠ 3 26 | * 27 | * 输出: [1,3,2] 28 | * 29 | * 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 30 | * 31 | */ 32 | 33 | // @lc code=start 34 | /** 35 | * Definition for a binary tree node. 36 | * function TreeNode(val) { 37 | * this.val = val; 38 | * this.left = this.right = null; 39 | * } 40 | */ 41 | /** 42 | * @param {TreeNode} root 43 | * @return {number[]} 44 | */ 45 | const inorderTraversal = (root, array = []) => { 46 | if (!root) { 47 | return array 48 | } 49 | 50 | inorderTraversal(root.left, array) 51 | array.push(root.val) 52 | inorderTraversal(root.right, array) 53 | 54 | return array 55 | } 56 | 57 | // @lc code=end 58 | const inorderTraversal2 = root => { 59 | const stack = [] 60 | const result = [] 61 | 62 | let current = root 63 | 64 | while (current || stack.length > 0) { 65 | while (current) { 66 | stack.push(current) 67 | current = current.left 68 | } 69 | 70 | current = stack.pop() 71 | result.push(current.val) 72 | current = current.right 73 | } 74 | 75 | return result 76 | } 77 | -------------------------------------------------------------------------------- /98.验证二叉搜索树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=98 lang=javascript 3 | * 4 | * [98] 验证二叉搜索树 5 | * 6 | * https://leetcode-cn.com/problems/validate-binary-search-tree/description/ 7 | * 8 | * algorithms 9 | * Medium (27.90%) 10 | * Likes: 484 11 | * Dislikes: 0 12 | * Total Accepted: 86.7K 13 | * Total Submissions: 292.8K 14 | * Testcase Example: '[2,1,3]' 15 | * 16 | * 给定一个二叉树,判断其是否是一个有效的二叉搜索树。 17 | * 18 | * 假设一个二叉搜索树具有如下特征: 19 | * 20 | * 21 | * 节点的左子树只包含小于当前节点的数。 22 | * 节点的右子树只包含大于当前节点的数。 23 | * 所有左子树和右子树自身必须也是二叉搜索树。 24 | * 25 | * 26 | * 示例 1: 27 | * 28 | * 输入: 29 | * ⁠ 2 30 | * ⁠ / \ 31 | * ⁠ 1 3 32 | * 输出: true 33 | * 34 | * 35 | * 示例 2: 36 | * 37 | * 输入: 38 | * ⁠ 5 39 | * ⁠ / \ 40 | * ⁠ 1 4 41 | * / \ 42 | * 3 6 43 | * 输出: false 44 | * 解释: 输入为: [5,1,4,null,null,3,6]。 45 | * 根节点的值为 5 ,但是其右子节点值为 4 。 46 | * 47 | * 48 | */ 49 | 50 | // @lc code=start 51 | /** 52 | * Definition for a binary tree node. 53 | * function TreeNode(val) { 54 | * this.val = val; 55 | * this.left = this.right = null; 56 | * } 57 | */ 58 | /** 59 | * @param {TreeNode} root 60 | * @return {boolean} 61 | */ 62 | const isValidBST = function (root) { 63 | const stack = [] 64 | let current = root 65 | let lastNode = '' 66 | 67 | while (current !== null || stack.length !== 0) { 68 | while (current !== null) { 69 | stack.push(current) 70 | current = current.left 71 | } 72 | 73 | current = stack.pop() 74 | 75 | if (lastNode !== '' && current.val <= lastNode) { 76 | return false 77 | } 78 | 79 | lastNode = current.val 80 | current = current.right 81 | } 82 | 83 | return true 84 | } 85 | // @lc code=end 86 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 moke 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LeetCode 2 | 3 | [![Travis](https://img.shields.io/badge/language-JavaScript-yellow.svg)]() 4 | 5 | ## 介绍 6 | 7 | 记录自己的 LeetCode 解题代码(以 JavaScript 为主) 8 | 9 | ## 指南 10 | 11 | ### 算法 12 | 13 | - 排序 14 | - 分治 15 | - 数学运算 16 | - 查找 17 | - DFS 和 BFS 18 | - 递归和循环 19 | - 回溯算法 20 | - 动态规划 21 | - 贪心算法 22 | 23 | ### 数据结构 24 | 25 | - 队列 & 栈 26 | - 数组和字符串 27 | - 链表 28 | - 哈希表 29 | - 二分查找 30 | - 二叉树 31 | - 二叉搜索树 32 | - N 叉树 33 | - 前缀树 34 | --------------------------------------------------------------------------------