├── .gitignore ├── 2765.最长交替子序列.js ├── 48.旋转图像.js ├── 922.按奇偶排序数组-ii.js ├── README.md ├── hashTable.js ├── index.html ├── index.js ├── 二分查找 ├── 153.寻找旋转排序数组中的最小值.js ├── 29.两数相除.js ├── 33.搜索旋转排序数组.js ├── 34.在排序数组中查找元素的第一个和最后一个位置.js ├── 35.搜索插入位置.js ├── 367.有效的完全平方数.js ├── 69.x-的平方根.js └── 704.二分查找.js ├── 其他 ├── 134.加油站.js ├── 136.只出现一次的数字.js ├── 1464.数组中两元素的最大乘积.js ├── 162.寻找峰值.js ├── 204.计数质数.js ├── 228.汇总区间.js ├── 231.2-的幂.js ├── 238.除自身以外数组的乘积.js ├── 326.3-的幂.js ├── 419.甲板上的战舰.js ├── 434.字符串中的单词数.js ├── 448.找到所有数组中消失的数字.js ├── 45.跳跃游戏-ii.js ├── 485.最大连续-1-的个数.js ├── 66.加一.js ├── 73.矩阵置零.js ├── 77.组合.js └── 796.旋转字符串.js ├── 动态规划 ├── 10.正则表达式匹配.js ├── 1143.最长公共子序列.js ├── 115.不同的子序列.js ├── 120.三角形最小路径和.js ├── 121.买卖股票的最佳时机.js ├── 122.买卖股票的最佳时机-ii.js ├── 123.买卖股票的最佳时机-iii.js ├── 131.分割回文串.js ├── 132.分割回文串-ii.js ├── 139.单词拆分.js ├── 152.乘积最大子数组.js ├── 1668.最大重复子字符串.js ├── 188.买卖股票的最佳时机-iv.js ├── 198.打家劫舍.js ├── 213.打家劫舍-ii.js ├── 221.最大正方形.js ├── 279.完全平方数.js ├── 300.最长递增子序列.js ├── 312.戳气球.js ├── 322.零钱兑换.js ├── 337.打家劫舍-iii.js ├── 343.整数拆分.js ├── 376.摆动序列.js ├── 516.最长回文子序列.js ├── 518.零钱兑换-ii.js ├── 53.最大子数组和.js ├── 55.跳跃游戏.js ├── 583.两个字符串的删除操作.js ├── 62.不同路径.js ├── 63.不同路径-ii.js ├── 64.最小路径和.js ├── 647.回文子串.js ├── 70.爬楼梯.js ├── 714.买卖股票的最佳时机含手续费.js ├── 718.最长重复子数组.js ├── 72.编辑距离.js └── 746.使用最小花费爬楼梯.js ├── 双指针 ├── 11.盛最多水的容器.js ├── 125.验证回文串.js ├── 15.三数之和.js ├── 16.最接近的三数之和.js ├── 165.比较版本号.js ├── 167.两数之和-ii-输入有序数组.js ├── 18.四数之和.js ├── 202.快乐数.js ├── 209.长度最小的子数组.js ├── 26.删除有序数组中的重复项.js ├── 27.移除元素.js ├── 283.移动零.js ├── 287.寻找重复数.js ├── 3.无重复字符的最长子串.js ├── 344.反转字符串.js ├── 349.两个数组的交集.js ├── 350.两个数组的交集-ii.js ├── 4.寻找两个正序数组的中位数.js ├── 42.接雨水.js ├── 443.压缩字符串.js ├── 455.分发饼干.js ├── 5.最长回文子串.js ├── 581.最短无序连续子数组.js ├── 75.颜色分类.js ├── 80.删除有序数组中的重复项-ii.js ├── 844.比较含退格的字符串.js ├── 88.合并两个有序数组.js ├── 905.按奇偶排序数组.js └── 977.有序数组的平方.js ├── 哈希表 ├── 1.两数之和.js ├── 128.最长连续序列.js ├── 1287.有序数组中出现次数超过-25-的元素.js ├── 137.只出现一次的数字-ii.js ├── 187.重复的dna序列.js ├── 205.同构字符串.js ├── 217.存在重复元素.js ├── 242.有效的字母异位词.js ├── 2744.最大字符串配对数目.js ├── 347.前-k-个高频元素.js ├── 387.字符串中的第一个唯一字符.js └── 41.缺失的第一个正数.js ├── 回溯 ├── 140.单词拆分-ii.js ├── 22.括号生成.js ├── 39.组合总和.js ├── 40.组合总和-ii.js ├── 46.全排列.js ├── 47.全排列-ii.js ├── 51.n-皇后.js ├── 78.子集.js ├── 79.单词搜索.js └── 93.复原-ip-地址.js ├── 字符串 ├── 14.最长公共前缀.js ├── 301.删除无效的括号.js ├── 409.最长回文串.js ├── 459.重复的子字符串.js ├── 58.最后一个单词的长度.js ├── 67.二进制求和.js └── 680.验证回文字符串-ⅱ.js ├── 手写题 ├── 寄生式组合继承.js ├── 最大异步任务并发数.js └── 深拷贝.js ├── 排序 ├── 169.多数元素.js ├── 179.最大数.js ├── 56.合并区间.js ├── 57.插入区间.js ├── 冒泡排序.js ├── 基数排序.js ├── 堆排序.js ├── 希尔排序.js ├── 归并排序.js ├── 快速排序.js ├── 插入排序.js ├── 桶排序.js └── 选择排序.js ├── 数学 ├── 118.杨辉三角.js ├── 119.杨辉三角-ii.js ├── 1588.所有奇数长度子数组的和.js ├── 258.各位相加.js ├── 453.最小操作次数使数组元素相等.js ├── 50.pow-x-n.js ├── 7.整数反转.js └── 9.回文数.js ├── 栈 ├── 1190.反转每对括号间的子串.js ├── 1249.移除无效的括号.js ├── 151.颠倒字符串中的单词.js ├── 1614.括号的最大嵌套深度.js ├── 20.有效的括号.js ├── 224.基本计算器.js ├── 225.用队列实现栈.js ├── 232.用栈实现队列.js ├── 316.去除重复字母.js ├── 32.最长有效括号.js ├── 331.验证二叉树的前序序列化.js ├── 341.扁平化嵌套列表迭代器.js ├── 402.移掉-k-位数字.js ├── 496.下一个更大元素-i.js ├── 581.最短无序连续子数组.js ├── 678.有效的括号字符串.js ├── 71.简化路径.js ├── 739.每日温度.js ├── 84.柱状图中最大的矩形.js ├── 85.最大矩形.js └── 916.单词子集.js ├── 树 ├── 100.相同的树.js ├── 1008.前序遍历构造二叉搜索树.js ├── 101.对称二叉树.js ├── 102.二叉树的层序遍历.js ├── 103.二叉树的锯齿形层序遍历.js ├── 104.二叉树的最大深度.js ├── 105.从前序与中序遍历序列构造二叉树.js ├── 106.从中序与后序遍历序列构造二叉树.js ├── 107.二叉树的层序遍历-ii.js ├── 108.将有序数组转换为二叉搜索树.js ├── 110.平衡二叉树.js ├── 111.二叉树的最小深度.js ├── 1110.删点成林.js ├── 112.路径总和.js ├── 113.路径总和-ii.js ├── 114.二叉树展开为链表.js ├── 116.填充每个节点的下一个右侧节点指针.js ├── 124.二叉树中的最大路径和.js ├── 129.求根节点到叶节点数字之和.js ├── 144.二叉树的前序遍历.js ├── 145.二叉树的后序遍历.js ├── 199.二叉树的右视图.js ├── 222.完全二叉树的节点个数.js ├── 226.翻转二叉树.js ├── 230.二叉搜索树中第k小的元素.js ├── 235.二叉搜索树的最近公共祖先.js ├── 236.二叉树的最近公共祖先.js ├── 257.二叉树的所有路径.js ├── 404.左叶子之和.js ├── 429.n-叉树的层序遍历.js ├── 437.路径总和-iii.js ├── 450.删除二叉搜索树中的节点.js ├── 509.斐波那契数.js ├── 515.在每个树行中找最大值.js ├── 543.二叉树的直径.js ├── 572.另一棵树的子树.js ├── 617.合并二叉树.js ├── 637.二叉树的层平均值.js ├── 652.寻找重复的子树.js ├── 654.最大二叉树.js ├── 687.最长同值路径.js ├── 700.二叉搜索树中的搜索.js ├── 701.二叉搜索树中的插入操作.js ├── 94.二叉树的中序遍历.js ├── 95.不同的二叉搜索树-ii.js ├── 96.不同的二叉搜索树.js ├── 979.在二叉树中分配硬币.js ├── 98.验证二叉搜索树.js └── 99.恢复二叉搜索树.js ├── 模拟 └── 54.螺旋矩阵.js ├── 滑动窗口 ├── 219.存在重复元素-ii.js ├── 30.串联所有单词的子串.js └── 904.水果成篮.js ├── 贪心 ├── 392.判断子序列.js ├── 435.无重叠区间.js ├── 452.用最少数量的箭引爆气球.js ├── 621.任务调度器.js ├── 670.最大交换.js ├── 674.最长连续递增序列.js ├── 769.最多能完成排序的块.js └── 860.柠檬水找零.js ├── 递归和迭代 ├── 200.岛屿数量.js ├── 695.岛屿的最大面积.js └── 90.子集-ii.js └── 链表 ├── 1019.链表中的下一个更大节点.js ├── 109.有序链表转换二叉搜索树.js ├── 117.填充每个节点的下一个右侧节点指针-ii.js ├── 1171.从链表中删去总和值为零的连续节点.js ├── 1290.二进制链表转整数.js ├── 1367.二叉树中的链表.js ├── 141.环形链表.js ├── 142.环形链表-ii.js ├── 143.重排链表.js ├── 146.lru-缓存.js ├── 147.对链表进行插入排序.js ├── 148.排序链表.js ├── 160.相交链表.js ├── 1669.合并两个链表.js ├── 1721.交换链表中的节点.js ├── 19.删除链表的倒数第-n-个结点.js ├── 2.两数相加.js ├── 203.移除链表元素.js ├── 2058.找出临界点之间的最小和最大距离.js ├── 206.反转链表.js ├── 2095.删除链表的中间节点.js ├── 21.合并两个有序链表.js ├── 2181.合并零之间的节点.js ├── 2296.设计一个文本编辑器.js ├── 23.合并k个升序链表.js ├── 234.回文链表.js ├── 237.删除链表中的节点.js ├── 24.两两交换链表中的节点.js ├── 2487.从链表中移除节点.js ├── 2807.在链表中插入最大公约数.js ├── 328.奇偶链表.js ├── 355.设计推特.js ├── 382.链表随机节点.js ├── 445.两数相加-ii.js ├── 61.旋转链表.js ├── 705.设计哈希集合.js ├── 707.设计链表.js ├── 725.分隔链表.js ├── 817.链表组件.js ├── 82.删除排序链表中的重复元素-ii.js ├── 83.删除排序链表中的重复元素.js ├── 86.分隔链表.js ├── 876.链表的中间结点.js └── 92.反转链表-ii.js /.gitignore: -------------------------------------------------------------------------------- 1 | .index.js -------------------------------------------------------------------------------- /2765.最长交替子序列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=2765 lang=javascript 3 | * 4 | * [2765] 最长交替子序列 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var alternatingSubarray = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 单层循环 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let res = -1; 20 | const n = nums.length; 21 | let firstIndex = 0; 22 | 23 | for (let i = 1; i < n; i++) { 24 | const length = i - firstIndex + 1; 25 | if (nums[i] - nums[firstIndex] === (length - 1) % 2) { 26 | res = Math.max(res, length); 27 | } else { 28 | if (nums[i] - nums[i - 1] === 1) { 29 | firstIndex = i - 1; 30 | res = Math.max(res, 2); 31 | } else { 32 | firstIndex = i; 33 | } 34 | } 35 | } 36 | 37 | return res; 38 | }; 39 | // @lc code=end 40 | -------------------------------------------------------------------------------- /48.旋转图像.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=48 lang=javascript 3 | * 4 | * [48] 旋转图像 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[][]} matrix 10 | * @return {void} Do not return anything, modify matrix in-place instead. 11 | */ 12 | var rotate = function (matrix) { 13 | const n = matrix.length; 14 | const result = new Array(n).fill(0).map(() => new Array(n).fill(0)); 15 | 16 | for (let i = 0; i < n; i++) { 17 | for (let j = 0; j < n; j++) { 18 | result[j][n - i - 1] = matrix[i][j]; 19 | } 20 | } 21 | 22 | for (let i = 0; i < n; i++) { 23 | for (let j = 0; j < n; j++) { 24 | matrix[i][j] = result[i][j]; 25 | } 26 | } 27 | }; 28 | // @lc code=end 29 | -------------------------------------------------------------------------------- /922.按奇偶排序数组-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=922 lang=javascript 3 | * 4 | * [922] 按奇偶排序数组 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number[]} 11 | */ 12 | var sortArrayByParityII = function (nums) { 13 | let j = 1; 14 | for (let i = 0; i < nums.length; i += 2) { 15 | if (nums[i] % 2 === 1) { 16 | while (nums[j] % 2 === 1 && j < nums.length) { 17 | j += 2; 18 | } 19 | [nums[i], nums[j]] = [nums[j], nums[i]]; 20 | } 21 | } 22 | 23 | return nums; 24 | }; 25 | // @lc code=end 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## JavaScript 版本算法刷题笔记 2 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | function deepCopy(target, map = new WeakMap()) { 2 | if (typeof target == null) return target; 3 | if (target instanceof Date) return new Date(target); 4 | if (target instanceof RegExp) return new RegExp(target); 5 | 6 | if (typeof target === "object") { 7 | const isArray = Array.isArray(target); 8 | 9 | const data = isArray ? [] : []; 10 | 11 | if (map.get(target)) return map.get(target); 12 | 13 | const keys = isArray ? undefined : Object.keys(target); 14 | map.set(data, target); 15 | 16 | helper(keys || target, (value, key) => { 17 | if (key) key = value; 18 | data[key] = deepCopy(target[key], map); 19 | }); 20 | 21 | return data; 22 | } else return target; 23 | } 24 | 25 | function helper(array, iteratee) { 26 | let index = 0; 27 | const n = array.length; 28 | 29 | while (index++ < n) { 30 | iteratee(array[index], index); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /二分查找/153.寻找旋转排序数组中的最小值.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=153 lang=javascript 3 | * 4 | * [153] 寻找旋转排序数组中的最小值 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var findMin = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 二分查找 16 | * @timeComplexity O(log N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let left = 0; 20 | let right = nums.length - 1; 21 | 22 | while (left < right) { 23 | const mid = Math.floor(((right - left) >> 1) + left); 24 | 25 | if (nums[mid] < nums[right]) right = mid; 26 | else left = mid + 1; 27 | } 28 | 29 | return nums[left]; 30 | }; 31 | // @lc code=end 32 | -------------------------------------------------------------------------------- /二分查找/29.两数相除.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=29 lang=javascript 3 | * 4 | * [29] 两数相除 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} dividend 10 | * @param {number} divisor 11 | * @return {number} 12 | */ 13 | var divide = function (dividend, divisor) { 14 | /** 15 | * @author xun 16 | * @method 类二分查找 17 | * @timeComplexity O((logC ) 18 | * @spaceComplexity O((logC) 19 | */ 20 | const MAX_VALUE = 2 ** 31 - 1; 21 | const MIN_VALUE = -(2 ** 31); 22 | 23 | if (dividend === MIN_VALUE && divisor === -1) return MAX_VALUE; 24 | 25 | let a = Math.abs(dividend); 26 | let b = Math.abs(divisor); 27 | let result = 0; 28 | 29 | for (let i = 31; i >= 0; i--) { 30 | if (a >>> i >= b) { 31 | if (i === 31) { 32 | a -= MAX_VALUE; 33 | a -= 1; 34 | result -= MIN_VALUE; 35 | } else { 36 | a -= b << i; 37 | result += 1 << i; 38 | } 39 | } 40 | } 41 | 42 | return dividend > 0 == divisor > 0 ? result : -result; 43 | }; 44 | // @lc code=end 45 | -------------------------------------------------------------------------------- /二分查找/33.搜索旋转排序数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=33 lang=javascript 3 | * 4 | * [33] 搜索旋转排序数组 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @param {number} target 11 | * @return {number} 12 | */ 13 | var search = function (nums, target) { 14 | /** 15 | * @author xun 16 | * @method 二分查找 17 | * @timeComplexity O(log n) 18 | * @spaceComplexity O(1) 19 | */ 20 | let left = 0; 21 | let right = nums.length - 1; 22 | 23 | while (left <= right) { 24 | let mid = Math.floor(((right - left) >> 1) + left); 25 | 26 | if (nums[mid] === target) return mid; 27 | 28 | if (nums[left] <= nums[mid]) { 29 | if (nums[left] <= target && target < nums[mid]) right = mid - 1; 30 | else left = mid + 1; 31 | } else { 32 | if (nums[mid] < target && target <= nums[right]) left = mid + 1; 33 | else right = mid - 1; 34 | } 35 | } 36 | 37 | return -1; 38 | }; 39 | // @lc code=end 40 | -------------------------------------------------------------------------------- /二分查找/35.搜索插入位置.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=35 lang=javascript 3 | * 4 | * [35] 搜索插入位置 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @param {number} target 11 | * @return {number} 12 | */ 13 | var searchInsert = function (nums, target) { 14 | /** 15 | * @author xun 16 | * @method 二分查找 17 | * @timeComplexity O(log N) 18 | * @spaceComplexity O(1) 19 | */ 20 | const length = nums.length; 21 | let left = 0; 22 | let right = length - 1; 23 | let ans = length; 24 | 25 | while (left <= right) { 26 | const mid = Math.floor(((right - left) >> 1) + left); 27 | if (target <= nums[mid]) { 28 | ans = mid; 29 | right = mid - 1; 30 | } else { 31 | left = mid + 1; 32 | } 33 | } 34 | return ans; 35 | }; 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /二分查找/367.有效的完全平方数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=367 lang=javascript 3 | * 4 | * [367] 有效的完全平方数 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} num 10 | * @return {boolean} 11 | */ 12 | var isPerfectSquare = function (num) { 13 | /** 14 | * @author xun 15 | * @method 二分查找 16 | * @timeComplexity O(log N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let left = 0; 20 | let right = num; 21 | 22 | while (left <= right) { 23 | const mid = Math.floor((right - left) / 2) + left; 24 | const square = mid * mid; 25 | 26 | if (square < num) left = mid + 1; 27 | else if (square > num) right = mid - 1; 28 | else return true; 29 | } 30 | return false; 31 | }; 32 | // @lc code=end 33 | -------------------------------------------------------------------------------- /二分查找/69.x-的平方根.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=69 lang=javascript 3 | * 4 | * [69] x 的平方根 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} x 10 | * @return {number} 11 | */ 12 | var mySqrt = function (x) { 13 | /** 14 | * @author xun 15 | * @method 二分查找 16 | * @timeComplexity O(log N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let left = 0; 20 | let right = x; 21 | 22 | while (left <= right) { 23 | let mid = Math.floor(((right - left) >> 1) + left); 24 | 25 | if (mid * mid < x) { 26 | left = mid + 1; 27 | } else if (mid * mid > x) { 28 | right = mid - 1; 29 | } else { 30 | return mid; 31 | } 32 | } 33 | 34 | return right; 35 | }; 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /二分查找/704.二分查找.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=704 lang=javascript 3 | * 4 | * [704] 二分查找 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @param {number} target 11 | * @return {number} 12 | */ 13 | var search = function (nums, target) { 14 | /** 15 | * @author xun 16 | * @method 二分查找 17 | * @timeComplexity O(log N) 18 | * @spaceComplexity O(1) 19 | */ 20 | let left = 0; 21 | let right = nums.length - 1; 22 | 23 | while (left <= right) { 24 | const mid = Math.floor((right - left) / 2) + left; 25 | 26 | if (nums[mid] === target) return mid; 27 | else if (nums[mid] > target) right = mid - 1; 28 | else left = mid + 1; 29 | } 30 | 31 | return -1; 32 | }; 33 | // @lc code=end 34 | -------------------------------------------------------------------------------- /其他/134.加油站.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=134 lang=javascript 3 | * 4 | * [134] 加油站 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} gas 10 | * @param {number[]} cost 11 | * @return {number} 12 | */ 13 | var canCompleteCircuit = function (gas, cost) { 14 | /** 15 | * @author xun 16 | * @method 一次遍历 17 | * @timeComplexity O(N) 18 | * @spaceComplexity O(1) 19 | */ 20 | const length = gas.length; 21 | 22 | let i = 0; 23 | while (i < length) { 24 | let subGas = 0; 25 | let subCost = 0; 26 | let current = 0; 27 | while (current < length) { 28 | const j = (i + current) % length; 29 | subGas += gas[j]; 30 | subCost += cost[j]; 31 | 32 | if (subCost > subGas) break; 33 | current++; 34 | } 35 | 36 | if (current === length) return i; 37 | else i = i + current + 1; 38 | } 39 | 40 | return -1; 41 | }; 42 | 43 | // @lc code=end 44 | -------------------------------------------------------------------------------- /其他/136.只出现一次的数字.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=136 lang=javascript 3 | * 4 | * [136] 只出现一次的数字 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var singleNumber = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 位运算 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | 20 | let result = 0; 21 | 22 | nums.forEach((num) => { 23 | result ^= num; 24 | }); 25 | 26 | return result; 27 | }; 28 | // @lc code=end 29 | -------------------------------------------------------------------------------- /其他/1464.数组中两元素的最大乘积.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1464 lang=javascript 3 | * 4 | * [1464] 数组中两元素的最大乘积 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var maxProduct = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 一次遍历,维护最大和次大值 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let x = nums[0]; 20 | let y = nums[1]; 21 | 22 | if (x < y) [x, y] = [y, x]; 23 | 24 | for (let i = 2; i < nums.length; i++) { 25 | if (nums[i] > x) { 26 | y = x; 27 | x = nums[i]; 28 | } else if (nums[i] > y) { 29 | y = nums[i]; 30 | } 31 | } 32 | 33 | return (x - 1) * (y - 1); 34 | }; 35 | // @lc code=end 36 | -------------------------------------------------------------------------------- /其他/162.寻找峰值.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=162 lang=javascript 3 | * 4 | * [162] 寻找峰值 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var findPeakElement = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 寻找最大值 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let index = 0; 20 | 21 | for (let i = 0; i < nums.length; i++) { 22 | if (nums[i] > nums[index]) index = i; 23 | } 24 | 25 | return index; 26 | }; 27 | // @lc code=end 28 | -------------------------------------------------------------------------------- /其他/204.计数质数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=204 lang=javascript 3 | * 4 | * [204] 计数质数 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} n 10 | * @return {number} 11 | */ 12 | var countPrimes = function (n) { 13 | /** 14 | * @author xun 15 | * @method 枚举 16 | * @timeComplexity O(N n) 17 | * @spaceComplexity O(1) 18 | */ 19 | let ans = 0; 20 | for (let i = 2; i < n; i++) ans += isPrime(i); 21 | 22 | return ans; 23 | 24 | function isPrime(x) { 25 | for (let i = 2; i * i <= x; i++) { 26 | if (x % i === 0) return 0; 27 | } 28 | return 1; 29 | } 30 | }; 31 | // @lc code=end 32 | -------------------------------------------------------------------------------- /其他/228.汇总区间.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=228 lang=javascript 3 | * 4 | * [228] 汇总区间 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {string[]} 11 | */ 12 | var summaryRanges = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 一次遍历 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const result = []; 20 | let i = 0; 21 | const length = nums.length; 22 | 23 | while (i < length) { 24 | const low = i; 25 | i++; 26 | while (i < length && nums[i] === nums[i - 1] + 1) { 27 | i++; 28 | } 29 | const high = i - 1; 30 | 31 | const temp = ["" + nums[low]]; 32 | 33 | if (low < high) { 34 | temp.push("->"); 35 | temp.push("" + nums[high]); 36 | } 37 | result.push(temp.join("")); 38 | } 39 | 40 | return result; 41 | }; 42 | // @lc code=end 43 | -------------------------------------------------------------------------------- /其他/231.2-的幂.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=231 lang=javascript 3 | * 4 | * [231] 2 的幂 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} n 10 | * @return {boolean} 11 | */ 12 | var isPowerOfTwo = function (n) { 13 | /** 14 | * @author xun 15 | * @method 判断是否为最大 22 的幂的约数 16 | * @timeComplexity O(1) 17 | * @spaceComplexity O(1) 18 | */ 19 | const BIG = 1 << 30; 20 | return n > 0 && BIG % n === 0; 21 | }; 22 | // @lc code=end 23 | -------------------------------------------------------------------------------- /其他/238.除自身以外数组的乘积.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=238 lang=javascript 3 | * 4 | * [238] 除自身以外数组的乘积 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number[]} 11 | */ 12 | var productExceptSelf = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 其他 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const length = nums.length; 20 | const result = new Array(nums.length).fill(0); 21 | 22 | result[0] = 1; 23 | for (let i = 1; i < length; i++) { 24 | result[i] = nums[i - 1] * result[i - 1]; 25 | } 26 | 27 | let R = 1; 28 | for (let i = length - 1; i >= 0; i--) { 29 | result[i] *= R; 30 | R *= nums[i]; 31 | } 32 | return result; 33 | }; 34 | // @lc code=end 35 | -------------------------------------------------------------------------------- /其他/326.3-的幂.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=326 lang=javascript 3 | * 4 | * [326] 3 的幂 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} n 10 | * @return {boolean} 11 | */ 12 | var isPowerOfThree = function (n) { 13 | /** 14 | * @author xun 15 | * @method 其他 16 | * @timeComplexity O(1) 17 | * @spaceComplexity O(1) 18 | */ 19 | return n > 0 && 3 ** 19 % n === 0; 20 | }; 21 | 22 | // @lc code=end 23 | -------------------------------------------------------------------------------- /其他/419.甲板上的战舰.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=419 lang=javascript 3 | * 4 | * [419] 甲板上的战舰 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {character[][]} board 10 | * @return {number} 11 | */ 12 | var countBattleships = function (board) { 13 | /** 14 | * @author xun 15 | * @method 枚举起点 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | 20 | const row = board.length; 21 | const col = board[0].length; 22 | 23 | let ans = 0; 24 | for (let i = 0; i < row; i++) { 25 | for (let j = 0; j < col; j++) { 26 | if (board[i][j] === "X") { 27 | if (i > 0 && board[i - 1][j] === "X") continue; 28 | 29 | if (j > 0 && board[i][j - 1] === "X") continue; 30 | 31 | ans++; 32 | } 33 | } 34 | } 35 | return ans; 36 | }; 37 | // @lc code=end 38 | -------------------------------------------------------------------------------- /其他/434.字符串中的单词数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=434 lang=javascript 3 | * 4 | * [434] 字符串中的单词数 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {number} 11 | */ 12 | var countSegments = function (s) { 13 | /** 14 | * @author xun 15 | * @method 原地法 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let result = 0; 20 | for (let i = 0; i < s.length; i++) { 21 | if ((i === 0 || s[i - 1] === " ") && s[i] === " ") result++; 22 | } 23 | 24 | return result; 25 | }; 26 | // @lc code=end 27 | -------------------------------------------------------------------------------- /其他/448.找到所有数组中消失的数字.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=448 lang=javascript 3 | * 4 | * [448] 找到所有数组中消失的数字 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number[]} 11 | */ 12 | var findDisappearedNumbers = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 原地修改 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const length = nums.length; 20 | 21 | for (const num of nums) { 22 | const x = (num - 1) % length; 23 | nums[x] += length; 24 | } 25 | 26 | const result = []; 27 | for (const [i, num] of nums.entries()) { 28 | if (num <= length) result.push(i + 1); 29 | } 30 | 31 | return result; 32 | }; 33 | // @lc code=end 34 | -------------------------------------------------------------------------------- /其他/45.跳跃游戏-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=45 lang=javascript 3 | * 4 | * [45] 跳跃游戏 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var jump = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 正向查找 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let currentIndex = 0; 20 | let nextIndex = 0; 21 | let step = 0; 22 | 23 | for (let i = 0; i < nums.length - 1; i++) { 24 | nextIndex = Math.max(nums[i] + i, nextIndex); 25 | 26 | if (i === currentIndex) { 27 | currentIndex = nextIndex; 28 | step++; 29 | } 30 | } 31 | 32 | return step; 33 | }; 34 | // @lc code=end 35 | -------------------------------------------------------------------------------- /其他/485.最大连续-1-的个数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=485 lang=javascript 3 | * 4 | * [485] 最大连续 1 的个数 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var findMaxConsecutiveOnes = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 一次遍历 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const length = nums.length; 20 | let maxCount = 0; 21 | let count = 0; 22 | 23 | for (let i = 0; i < length; i++) { 24 | if (nums[i] === 1) count++; 25 | else { 26 | maxCount = Math.max(maxCount, count); 27 | count = 0; 28 | } 29 | } 30 | maxCount = Math.max(maxCount, count); 31 | 32 | return maxCount; 33 | }; 34 | // @lc code=end 35 | -------------------------------------------------------------------------------- /其他/66.加一.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=66 lang=javascript 3 | * 4 | * [66] 加一 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} digits 10 | * @return {number[]} 11 | */ 12 | var plusOne = function (digits) { 13 | /** 14 | * @author xun 15 | * @method 找出最长的后缀 9 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const length = digits.length; 20 | for (let i = length - 1; i >= 0; i--) { 21 | if (digits[i] !== 9) { 22 | digits[i]++; 23 | for (let j = i + 1; j < length; j++) { 24 | digits[j] = 0; 25 | } 26 | return digits; 27 | } 28 | } 29 | const ans = new Array(length + 1).fill(0); 30 | ans[0] = 1; 31 | 32 | return ans; 33 | }; 34 | // @lc code=end 35 | -------------------------------------------------------------------------------- /其他/73.矩阵置零.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=73 lang=javascript 3 | * 4 | * [73] 矩阵置零 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[][]} matrix 10 | * @return {void} Do not return anything, modify matrix in-place instead. 11 | */ 12 | var setZeroes = function (matrix) { 13 | /** 14 | * @author xun 15 | * @method 其他 16 | * @timeComplexity O(MN) 17 | * @spaceComplexity O(1) 18 | */ 19 | const m = matrix.length; 20 | const n = matrix[0].length; 21 | 22 | let flag = false; 23 | for (let i = 0; i < m; i++) { 24 | if (matrix[i][0] === 0) flag = true; 25 | 26 | for (let j = 1; j < n; j++) { 27 | if (matrix[i][j] === 0) matrix[i][0] = matrix[0][j] = 0; 28 | } 29 | } 30 | 31 | for (let i = m - 1; i >= 0; i--) { 32 | for (let j = 1; j < n; j++) { 33 | if (matrix[i][0] === 0 || matrix[0][j] === 0) matrix[i][j] = 0; 34 | } 35 | 36 | if (flag) matrix[i][0] = 0; 37 | } 38 | }; 39 | // @lc code=end 40 | -------------------------------------------------------------------------------- /其他/77.组合.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=77 lang=javascript 3 | * 4 | * [77] 组合 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} n 10 | * @param {number} k 11 | * @return {number[][]} 12 | */ 13 | var combine = function (n, k) { 14 | /** 15 | * @author xun 16 | * @method 字典序法实现组合型枚举 17 | * @timeComplexity O(N) 18 | * @spaceComplexity O(K) 19 | */ 20 | const temp = []; 21 | const ans = []; 22 | 23 | for (let i = 1; i <= k; i++) { 24 | temp.push(i); 25 | } 26 | 27 | temp.push(n + 1); 28 | 29 | let j = 0; 30 | while (j < k) { 31 | ans.push(temp.slice(0, k)); 32 | j = 0; 33 | 34 | while (j < k && temp[j] + 1 === temp[j + 1]) { 35 | temp[j] = j + 1; 36 | j++; 37 | } 38 | ++temp[j]; 39 | } 40 | return ans; 41 | }; 42 | // @lc code=end 43 | -------------------------------------------------------------------------------- /其他/796.旋转字符串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=796 lang=javascript 3 | * 4 | * [796] 旋转字符串 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @param {string} goal 11 | * @return {boolean} 12 | */ 13 | var rotateString = function (s, goal) { 14 | /** 15 | * @author xun 16 | * @method 搜索子字符串 17 | * @timeComplexity O(N) 18 | * @spaceComplexity O(N) 19 | */ 20 | return s.length === goal.length && (s + s).indexOf(goal) !== -1; 21 | }; 22 | // @lc code=end 23 | -------------------------------------------------------------------------------- /动态规划/10.正则表达式匹配.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=10 lang=javascript 3 | * 4 | * [10] 正则表达式匹配 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @param {string} p 11 | * @return {boolean} 12 | */ 13 | var isMatch = function (s, p) { 14 | /** 15 | * @author xun 16 | * @method 动态规划 17 | * @timeComplexity O(MN) 18 | * @spaceComplexity O(MN) 19 | */ 20 | function getIsMatch(s, p) { 21 | if (p.length === 0) return !s.length; 22 | 23 | let match = false; 24 | if (s.length > 0 && (s[0] === p[0] || p[0] === ".")) match = true; 25 | 26 | if (p.length > 1 && p[1] === "*") { 27 | return getIsMatch(s, p.slice(2)) || (match && getIsMatch(s.slice(1), p)); 28 | } else return match && getIsMatch(s.slice(1), p.slice(1)); 29 | } 30 | return getIsMatch(s, p); 31 | }; 32 | // @lc code=end 33 | -------------------------------------------------------------------------------- /动态规划/1143.最长公共子序列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1143 lang=javascript 3 | * 4 | * [1143] 最长公共子序列 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} text1 10 | * @param {string} text2 11 | * @return {number} 12 | */ 13 | var longestCommonSubsequence = function (text1, text2) { 14 | /** 15 | * @author xun 16 | * @method 动态规划 17 | * @timeComplexity O(MN) 18 | * @spaceComplexity O(MN) 19 | */ 20 | const m = text1.length; 21 | const n = text2.length; 22 | 23 | const path = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0)); 24 | 25 | for (let i = 1; i <= m; i++) { 26 | const c1 = text1[i - 1]; 27 | for (let j = 1; j <= n; j++) { 28 | const c2 = text2[j - 1]; 29 | 30 | if (c1 === c2) path[i][j] = path[i - 1][j - 1] + 1; 31 | else path[i][j] = Math.max(path[i - 1][j], path[i][j - 1]); 32 | } 33 | } 34 | 35 | return path[m][n]; 36 | }; 37 | // @lc code=end 38 | -------------------------------------------------------------------------------- /动态规划/115.不同的子序列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=115 lang=javascript 3 | * 4 | * [115] 不同的子序列 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @param {string} t 11 | * @return {number} 12 | */ 13 | var numDistinct = function (s, t) { 14 | /** 15 | * @author xun 16 | * @method 动态规划 17 | * @timeComplexity O(mn) 18 | * @spaceComplexity O(mn) 19 | */ 20 | const m = s.length; 21 | const n = t.length; 22 | 23 | if (m < n) return 0; 24 | 25 | const path = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0)); 26 | 27 | for (let i = 0; i <= m; i++) { 28 | path[i][n] = 1; 29 | } 30 | 31 | for (let i = m - 1; i >= 0; i--) { 32 | for (let j = n - 1; j >= 0; j--) { 33 | if (s[i] === t[j]) path[i][j] = path[i + 1][j + 1] + path[i + 1][j]; 34 | else path[i][j] = path[i + 1][j]; 35 | } 36 | } 37 | 38 | return path[0][0]; 39 | }; 40 | // @lc code=end 41 | -------------------------------------------------------------------------------- /动态规划/120.三角形最小路径和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=120 lang=javascript 3 | * 4 | * [120] 三角形最小路径和 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[][]} triangle 10 | * @return {number} 11 | */ 12 | var minimumTotal = function (triangle) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const row = triangle.length; 20 | 21 | if (row === 0) return 0; 22 | 23 | for (let i = row - 2; i >= 0; i--) { 24 | for (let j = 0, col = triangle[i].length; j < col; j++) { 25 | const min = Math.min(triangle[i + 1][j], triangle[i + 1][j + 1]); 26 | triangle[i][j] += min; 27 | } 28 | } 29 | 30 | return triangle[0][0]; 31 | }; 32 | // @lc code=end 33 | -------------------------------------------------------------------------------- /动态规划/121.买卖股票的最佳时机.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=121 lang=javascript 3 | * 4 | * [121] 买卖股票的最佳时机 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} prices 10 | * @return {number} 11 | */ 12 | var maxProfit = function (prices) { 13 | /** 14 | * @author xun 15 | * @method 一次遍历 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let min = prices[0]; 20 | let max = 0; 21 | 22 | for (const p of prices) { 23 | max = Math.max(max, p - min); 24 | min = Math.min(p, min); 25 | } 26 | 27 | return max; 28 | }; 29 | // @lc code=end 30 | -------------------------------------------------------------------------------- /动态规划/122.买卖股票的最佳时机-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=122 lang=javascript 3 | * 4 | * [122] 买卖股票的最佳时机 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} prices 10 | * @return {number} 11 | */ 12 | var maxProfit = function (prices) { 13 | /** 14 | * @author xun 15 | * @method 贪心 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const length = prices.length; 20 | let result = 0; 21 | for (let i = 1; i < length; i++) { 22 | result += Math.max(0, prices[i] - prices[i - 1]); 23 | } 24 | 25 | return result; 26 | }; 27 | // @lc code=end 28 | -------------------------------------------------------------------------------- /动态规划/123.买卖股票的最佳时机-iii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=123 lang=javascript 3 | * 4 | * [123] 买卖股票的最佳时机 III 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} prices 10 | * @return {number} 11 | */ 12 | var maxProfit = function (prices) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const length = prices.length; 20 | 21 | let one = -prices[0]; 22 | let two = -prices[0]; 23 | 24 | let count1 = 0; 25 | let count2 = 0; 26 | 27 | for (let i = 1; i < length; i++) { 28 | one = Math.max(one, -prices[i]); 29 | count1 = Math.max(count1, one + prices[i]); 30 | 31 | two = Math.max(two, count1 - prices[i]); 32 | count2 = Math.max(count2, two + prices[i]); 33 | } 34 | 35 | return count2; 36 | }; 37 | // @lc code=end 38 | -------------------------------------------------------------------------------- /动态规划/131.分割回文串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=131 lang=javascript 3 | * 4 | * [131] 分割回文串 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {string[][]} 11 | */ 12 | function isPalindrome(s, l, r) { 13 | for (let i = l, j = r; i < j; i++, j--) { 14 | if (s[i] !== s[j]) return false; 15 | } 16 | return true; 17 | } 18 | 19 | var partition = function (s) { 20 | /** 21 | * @author xun 22 | * @method 回溯+动态规划预处理 23 | * @timeComplexity O(n*2**n) 24 | * @spaceComplexity O(N**2) 25 | */ 26 | const length = s.length; 27 | const path = new Array(length) 28 | .fill(0) 29 | .map(() => new Array(length).fill(true)); 30 | 31 | const result = []; 32 | const ans = []; 33 | 34 | for (let i = length - 1; i >= 0; i--) { 35 | for (let j = i + 1; j < length; j++) { 36 | path[i][j] = s[i] === s[j] && path[i + 1][j - 1]; 37 | } 38 | } 39 | 40 | function dfs(x) { 41 | if (x === length) { 42 | result.push(ans.slice()); 43 | return; 44 | } 45 | 46 | for (let y = x; y < length; y++) { 47 | if (path[x][y]) { 48 | ans.push(s.slice(x, y + 1)); 49 | dfs(y + 1); 50 | ans.pop(); 51 | } 52 | } 53 | } 54 | dfs(0); 55 | 56 | return result; 57 | }; 58 | // @lc code=end 59 | -------------------------------------------------------------------------------- /动态规划/132.分割回文串-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=132 lang=javascript 3 | * 4 | * [132] 分割回文串 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {number} 11 | */ 12 | var minCut = function (s) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N*N) 17 | * @spaceComplexity O(N*N) 18 | */ 19 | const n = s.length; 20 | const path = new Array(n).fill(0).map(() => new Array(n).fill(true)); 21 | 22 | for (let i = n - 1; i >= 0; --i) { 23 | for (let j = i + 1; j < n; ++j) { 24 | path[i][j] = s[i] == s[j] && path[i + 1][j - 1]; 25 | } 26 | } 27 | 28 | const f = new Array(n).fill(Number.MAX_SAFE_INTEGER); 29 | for (let i = 0; i < n; ++i) { 30 | if (path[0][i]) { 31 | f[i] = 0; 32 | } else { 33 | for (let j = 0; j < i; ++j) { 34 | if (path[j + 1][i]) { 35 | f[i] = Math.min(f[i], f[j] + 1); 36 | } 37 | } 38 | } 39 | } 40 | 41 | return f[n - 1]; 42 | }; 43 | // @lc code=end 44 | -------------------------------------------------------------------------------- /动态规划/139.单词拆分.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=139 lang=javascript 3 | * 4 | * [139] 单词拆分 5 | */ 6 | // @lc code=start 7 | /** 8 | * @param {string} s 9 | * @param {string[]} wordDict 10 | * @return {boolean} 11 | */ 12 | 13 | var wordBreak = function (s, wordDict) { 14 | /** 15 | * @author xun 16 | * @method 动态规划 17 | * @timeComplexity O(N*N) 18 | * @spaceComplexity O(N) 19 | */ 20 | const length = s.length; 21 | const path = new Array(length + 1).fill(false); 22 | // 空子前缀串默认能被拆分 23 | path[0] = true; 24 | 25 | for (let i = 1; i <= length; i++) { 26 | for (let j = 0; j <= i - 1; j++) { 27 | //存在一个字串能被拆分,并且剩余的字符串能在单词表中找到就表示当前单词能被拆分 28 | if (path[j] && wordDict.indexOf(s.substring(j, i)) !== -1) { 29 | path[i] = true; 30 | } 31 | } 32 | } 33 | return path[length]; 34 | }; 35 | 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /动态规划/152.乘积最大子数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=152 lang=javascript 3 | * 4 | * [152] 乘积最大子数组 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var maxProduct = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let result = -Infinity; 20 | 21 | let currentMax = 1; 22 | let currentMin = 1; 23 | 24 | for (const num of nums) { 25 | if (num < 0) [currentMax, currentMin] = [currentMin, currentMax]; 26 | 27 | currentMax = Math.max(currentMax * num, num); 28 | currentMin = Math.min(currentMin * num, num); 29 | 30 | result = Math.max(result, currentMax); 31 | } 32 | return result; 33 | }; 34 | // @lc code=end 35 | -------------------------------------------------------------------------------- /动态规划/1668.最大重复子字符串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1668 lang=javascript 3 | * 4 | * [1668] 最大重复子字符串 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} sequence 10 | * @param {string} word 11 | * @return {number} 12 | */ 13 | var maxRepeating = function (sequence, word) { 14 | /** 15 | * @author xun 16 | * @method 动态规划 17 | * @timeComplexity O(MN) 18 | * @spaceComplexity O(N) 19 | */ 20 | const n = sequence.length; 21 | const m = word.length; 22 | if (n < m) return 0; 23 | 24 | const path = new Array(n).fill(0); 25 | for (let i = m - 1; i < n; i++) { 26 | let valid = true; 27 | for (let j = 0; j < m; j++) { 28 | if (sequence[i - m + j + 1] !== word[j]) { 29 | valid = false; 30 | break; 31 | } 32 | } 33 | if (valid) path[i] = (i === m - 1 ? 0 : path[i - m]) + 1; 34 | } 35 | 36 | return Math.max(...path); 37 | }; 38 | // @lc code=end 39 | -------------------------------------------------------------------------------- /动态规划/188.买卖股票的最佳时机-iv.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=188 lang=javascript 3 | * 4 | * [188] 买卖股票的最佳时机 IV 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} k 10 | * @param {number[]} prices 11 | * @return {number} 12 | */ 13 | var maxProfit = function (k, prices) { 14 | /** 15 | * @author xun 16 | * @method 动态规划 17 | * @timeComplexity O(n min(n,k)) 18 | * @spaceComplexity O(n min(n,k)) 19 | */ 20 | const n = prices.length; 21 | if (!n) return 0; 22 | 23 | k = Math.min(k, Math.floor(n / 2)); 24 | const buy = new Array(k + 1).fill(0); 25 | const sell = new Array(k + 1).fill(0); 26 | 27 | [buy[0], sell[0]] = [-prices[0], 0]; 28 | 29 | for (let i = 1; i < k + 1; i++) { 30 | buy[i] = sell[i] = -Number.MAX_VALUE; 31 | } 32 | 33 | for (let i = 1; i < n; i++) { 34 | buy[0] = Math.max(buy[0], sell[0] - prices[i]); 35 | for (let j = 1; j < k + 1; j++) { 36 | buy[j] = Math.max(buy[j], sell[j] - prices[i]); 37 | sell[j] = Math.max(sell[j], buy[j - 1] + prices[i]); 38 | } 39 | } 40 | 41 | return Math.max(...sell); 42 | }; 43 | // @lc code=end 44 | -------------------------------------------------------------------------------- /动态规划/198.打家劫舍.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=198 lang=javascript 3 | * 4 | * [198] 打家劫舍 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var rob = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const path = [nums[0], Math.max(nums[0], nums[1])]; 20 | 21 | for (let i = 2; i < nums.length; i++) { 22 | path[i] = Math.max(path[i - 1], path[i - 2] + nums[i]); 23 | } 24 | 25 | return path[nums.length - 1]; 26 | }; 27 | // @lc code=end 28 | -------------------------------------------------------------------------------- /动态规划/213.打家劫舍-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=213 lang=javascript 3 | * 4 | * [213] 打家劫舍 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var rob = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const length = nums.length; 20 | 21 | if (length === 1) return nums[0]; 22 | else if (length === 2) return Math.max(nums[0], nums[1]); 23 | return Math.max(range(nums, 0, length - 2), range(nums, 1, length - 1)); 24 | }; 25 | 26 | function range(nums, start, end) { 27 | let first = nums[start]; 28 | let second = Math.max(nums[start], nums[start + 1]); 29 | 30 | for (let i = start + 2; i <= end; i++) { 31 | const temp = second; 32 | second = Math.max(first + nums[i], second); 33 | first = temp; 34 | } 35 | return second; 36 | } 37 | 38 | // @lc code=end 39 | -------------------------------------------------------------------------------- /动态规划/221.最大正方形.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=221 lang=javascript 3 | * 4 | * [221] 最大正方形 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {character[][]} matrix 10 | * @return {number} 11 | */ 12 | var maximalSquare = function (matrix) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(N) 18 | */ 19 | if (!matrix || matrix.length === 0 || matrix[0].length === 0) return 0; 20 | 21 | let maxSide = 0; 22 | let row = matrix.length; 23 | let column = matrix[0].length; 24 | 25 | const path = new Array(row).fill().map(() => new Array(column)); 26 | 27 | for (let i = 0; i < matrix.length; i++) { 28 | for (let j = 0; j < matrix[i].length; j++) { 29 | if (matrix[i][j] === "1") { 30 | if (i === 0 || j === 0) path[i][j] = 1; 31 | else { 32 | path[i][j] = Math.min( 33 | Math.min(path[i - 1][j], path[i][j - 1], path[i - 1][j - 1]) + 1 34 | ); 35 | } 36 | } else { 37 | path[i][j] = 0; 38 | } 39 | maxSide = Math.max(path[i][j], maxSide); 40 | } 41 | } 42 | 43 | return maxSide * maxSide; 44 | }; 45 | // @lc code=end 46 | -------------------------------------------------------------------------------- /动态规划/279.完全平方数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=279 lang=javascript 3 | * 4 | * [279] 完全平方数 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} n 10 | * @return {number} 11 | */ 12 | var numSquares = function (n) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N** 2/3) 17 | * @spaceComplexity O(N) 18 | */ 19 | const path = new Array(n + 1).fill(0); 20 | 21 | for (let i = 1; i <= n; i++) { 22 | let min = Number.MAX_VALUE; 23 | for (let j = 1; j * j <= i; j++) { 24 | min = Math.min(min, path[i - j * j]); 25 | } 26 | path[i] = min + 1; 27 | } 28 | return path[n]; 29 | }; 30 | // @lc code=end 31 | -------------------------------------------------------------------------------- /动态规划/300.最长递增子序列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=300 lang=javascript 3 | * 4 | * [300] 最长递增子序列 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var lengthOfLIS = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N**2) 17 | * @spaceComplexity O(N) 18 | */ 19 | const dp = new Array(nums.length).fill(1); 20 | 21 | for (let i = 0; i < nums.length; i++) { 22 | for (let j = 0; j < i; j++) { 23 | if (nums[i] > nums[j]) { 24 | dp[i] = Math.max(dp[i], dp[j] + 1); 25 | } 26 | } 27 | } 28 | 29 | return Math.max(...dp); 30 | }; 31 | // @lc code=end 32 | -------------------------------------------------------------------------------- /动态规划/312.戳气球.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=312 lang=javascript 3 | * 4 | * [312] 戳气球 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var maxCoins = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const n = nums.length; 20 | const points = new Array(n + 2); 21 | points[0] = points[n + 1] = 1; 22 | 23 | for (let i = 1; i <= n; i++) { 24 | points[i] = nums[i - 1]; 25 | } 26 | 27 | const path = new Array(n + 2).fill(0).map(() => new Array(n + 2).fill(0)); 28 | for (let i = n; i >= 0; i--) { 29 | for (let j = i + 1; j < n + 2; j++) { 30 | for (let k = i + 1; k < j; k++) { 31 | path[i][j] = Math.max( 32 | path[i][j], 33 | path[i][k] + path[k][j] + points[i] * points[j] * points[k] 34 | ); 35 | } 36 | } 37 | } 38 | return path[0][n + 1]; 39 | }; 40 | // @lc code=end 41 | -------------------------------------------------------------------------------- /动态规划/322.零钱兑换.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=322 lang=javascript 3 | * 4 | * [322] 零钱兑换 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} coins 10 | * @param {number} amount 11 | * @return {number} 12 | */ 13 | var coinChange = function (coins, amount) { 14 | /** 15 | * @author xun 16 | * @method 动态规划 17 | * @timeComplexity O(SN)其中 SS 是金额,nn 是面额数。 18 | * @spaceComplexity O(S) 19 | */ 20 | if (amount === 0) return 0; 21 | 22 | const path = new Array(amount + 1).fill(Infinity); 23 | path[0] = 0; 24 | 25 | for (let i = 1; i <= amount; i++) { 26 | for (const number of coins) { 27 | if (i >= number) path[i] = Math.min(path[i], path[i - number] + 1); 28 | } 29 | } 30 | 31 | return path[amount] === Infinity ? -1 : path[amount]; 32 | }; 33 | 34 | // @lc code=end 35 | -------------------------------------------------------------------------------- /动态规划/337.打家劫舍-iii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=337 lang=javascript 3 | * 4 | * [337] 打家劫舍 III 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {number} 19 | */ 20 | var rob = function (root) { 21 | /** 22 | * @author xun 23 | * @method 动态规划 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | const f = new Map(); 28 | const g = new Map(); 29 | 30 | function dfs(node) { 31 | if (node === null) return; 32 | 33 | dfs(node.left); 34 | dfs(node.right); 35 | 36 | f.set(node, node.val + (g.get(node.left) || 0) + (g.get(node.right) || 0)); 37 | g.set( 38 | node, 39 | Math.max(f.get(node.left) || 0, g.get(node.left) || 0) + 40 | Math.max(f.get(node.right) || 0, g.get(node.right) || 0) 41 | ); 42 | } 43 | dfs(root); 44 | return Math.max(f.get(root) || 0, g.get(root) || 0); 45 | }; 46 | // @lc code=end 47 | -------------------------------------------------------------------------------- /动态规划/343.整数拆分.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=343 lang=javascript 3 | * 4 | * [343] 整数拆分 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} n 10 | * @return {number} 11 | */ 12 | var integerBreak = function (n) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | if (n <= 3) return n - 1; 20 | const path = new Array(n + 1).fill(0); 21 | path[1] = 1; 22 | path[2] = 1; 23 | for (let i = 3; i <= n; i++) { 24 | for (let j = 1; j <= i - j; j++) { 25 | path[i] = Math.max(path[i], j * (i - j), j * path[i - j]); 26 | } 27 | } 28 | return path[n]; 29 | }; 30 | // @lc code=end 31 | -------------------------------------------------------------------------------- /动态规划/376.摆动序列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=376 lang=javascript 3 | * 4 | * [376] 摆动序列 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var wiggleMaxLength = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const n = nums.length; 20 | 21 | if (n < 2) return n; 22 | 23 | let up = 1; 24 | let down = 1; 25 | 26 | for (let i = 1; i < n; i++) { 27 | if (nums[i] > nums[i - 1]) { 28 | up = Math.max(up, down + 1); 29 | } else if (nums[i] < nums[i - 1]) { 30 | down = Math.max(up + 1, down); 31 | } 32 | } 33 | 34 | return Math.max(up, down); 35 | }; 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /动态规划/516.最长回文子序列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=516 lang=javascript 3 | * 4 | * [516] 最长回文子序列 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {number} 11 | */ 12 | var longestPalindromeSubseq = function (s) { 13 | const length = s.length; 14 | const path = new Array(length).fill(0).map(() => new Array(length).fill(0)); 15 | 16 | for (let i = length - 1; i >= 0; i--) { 17 | path[i][i] = 1; 18 | const c1 = s[i]; 19 | for (let j = 1 + i; j < length; j++) { 20 | const c2 = s[j]; 21 | if (c1 === c2) { 22 | path[i][j] = path[i + 1][j - 1] + 2; 23 | } else { 24 | path[i][j] = Math.max(path[i + 1][j], path[i][j - 1]); 25 | } 26 | } 27 | } 28 | return path[0][length - 1]; 29 | }; 30 | // @lc code=end 31 | -------------------------------------------------------------------------------- /动态规划/518.零钱兑换-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=518 lang=javascript 3 | * 4 | * [518] 零钱兑换 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} amount 10 | * @param {number[]} coins 11 | * @return {number} 12 | */ 13 | var change = function (amount, coins) { 14 | /** 15 | * @author xun 16 | * @method 动态规划 17 | * @timeComplexity O(amount * N) 18 | * @spaceComplexity O(amount) 19 | */ 20 | const path = new Array(amount + 1).fill(0); 21 | path[0] = 1; 22 | 23 | for (let i = 0; i < coins.length; i++) { 24 | for (let j = coins[i]; j <= amount; j++) { 25 | path[j] += path[j - coins[i]]; 26 | } 27 | } 28 | 29 | return path[amount]; 30 | }; 31 | // @lc code=end 32 | -------------------------------------------------------------------------------- /动态规划/53.最大子数组和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=53 lang=javascript 3 | * 4 | * [53] 最大子数组和 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var maxSubArray = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let previous = 0; 20 | let maxAns = nums[0]; 21 | 22 | nums.forEach((x) => { 23 | previous = Math.max(previous + x, x); 24 | maxAns = Math.max(maxAns, previous); 25 | }); 26 | 27 | return maxAns; 28 | }; 29 | // @lc code=end 30 | -------------------------------------------------------------------------------- /动态规划/55.跳跃游戏.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=55 lang=javascript 3 | * 4 | * [55] 跳跃游戏 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {boolean} 11 | */ 12 | var canJump = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let end = nums.length - 1; 20 | 21 | for (let i = nums.length - 2; i >= 0; i--) { 22 | if (end - i <= nums[i]) { 23 | end = i; 24 | } 25 | } 26 | // 如果 end 能回到起点 27 | return end === 0; 28 | }; 29 | // @lc code=end 30 | -------------------------------------------------------------------------------- /动态规划/583.两个字符串的删除操作.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=583 lang=javascript 3 | * 4 | * [583] 两个字符串的删除操作 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} word1 10 | * @param {string} word2 11 | * @return {number} 12 | */ 13 | var minDistance = function (word1, word2) { 14 | /** 15 | * @author xun 16 | * @method 动态规划 17 | * @timeComplexity O(MN) 18 | * @spaceComplexity O(MN) 19 | */ 20 | const m = word1.length; 21 | const n = word2.length; 22 | 23 | const path = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0)); 24 | 25 | for (let i = 1; i <= m; i++) path[i][0] = i; 26 | 27 | for (let i = 1; i <= n; i++) path[0][i] = i; 28 | 29 | for (let i = 1; i <= m; i++) { 30 | const str1 = word1[i - 1]; 31 | 32 | for (let j = 1; j <= n; j++) { 33 | const str2 = word2[j - 1]; 34 | if (str1 === str2) path[i][j] = path[i - 1][j - 1]; 35 | else path[i][j] = Math.min(path[i - 1][j], path[i][j - 1]) + 1; 36 | } 37 | } 38 | 39 | return path[m][n]; 40 | }; 41 | // @lc code=end 42 | -------------------------------------------------------------------------------- /动态规划/62.不同路径.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=62 lang=javascript 3 | * 4 | * [62] 不同路径 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} m 10 | * @param {number} n 11 | * @return {number} 12 | */ 13 | var uniquePaths = function (m, n) { 14 | /** 15 | * @author xun 16 | * @method 动态规划 17 | * @timeComplexity O(mn) 18 | * @spaceComplexity O(mn) 19 | */ 20 | // const path = new Array(m).fill(0).map(() => new Array(n).fill(1)); 21 | 22 | // for (let i = 1; i < m; i++) { 23 | // for (let j = 1; j < n; j++) { 24 | // path[i][j] = path[i - 1][j] + path[i][j - 1]; 25 | // } 26 | // } 27 | // return path[m - 1][n - 1]; 28 | /** 29 | * @author xun 30 | * @method 组合数学 31 | * @timeComplexity O(N) 32 | * @spaceComplexity O(1) 33 | */ 34 | let result = 1; 35 | for (let i = n, j = 1; j < m; ++i, ++j) { 36 | result = Math.floor((result * i) / j); 37 | } 38 | return result; 39 | }; 40 | // @lc code=end 41 | -------------------------------------------------------------------------------- /动态规划/63.不同路径-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=63 lang=javascript 3 | * 4 | * [63] 不同路径 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[][]} obstacleGrid 10 | * @return {number} 11 | */ 12 | var uniquePathsWithObstacles = function (obstacleGrid) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(MN) 17 | * @spaceComplexity O(MN) 18 | */ 19 | let n = obstacleGrid.length; 20 | let m = obstacleGrid[0].length; 21 | 22 | const path = new Array(n).fill().map(() => new Array(m).fill(0)); 23 | 24 | for (let i = 0; i < n && obstacleGrid[i][0] === 0; i++) { 25 | path[i][0] = 1; 26 | } 27 | 28 | for (let i = 0; i < m && obstacleGrid[0][i] === 0; i++) { 29 | path[0][i] = 1; 30 | } 31 | 32 | for (let i = 1; i < n; i++) { 33 | for (let j = 1; j < m; j++) { 34 | path[i][j] = 35 | obstacleGrid[i][j] === 1 ? 0 : path[i - 1][j] + path[i][j - 1]; 36 | } 37 | } 38 | return path[n - 1][m - 1]; 39 | }; 40 | // @lc code=end 41 | -------------------------------------------------------------------------------- /动态规划/64.最小路径和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=64 lang=javascript 3 | * 4 | * [64] 最小路径和 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[][]} grid 10 | * @return {number} 11 | */ 12 | var minPathSum = function (grid) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(mn) 17 | * @spaceComplexity O(mn) 18 | */ 19 | let m = grid.length; 20 | let n = grid[0].length; 21 | 22 | if (n === 0 || m === 0) return 0; 23 | 24 | const path = new Array(m).fill().map(() => new Array(n).fill(0)); 25 | 26 | path[0][0] = grid[0][0]; 27 | 28 | for (let i = 1; i < n; i++) { 29 | path[0][i] = path[0][i - 1] + grid[0][i]; 30 | } 31 | 32 | for (let i = 1; i < m; i++) { 33 | path[i][0] = path[i - 1][0] + grid[i][0]; 34 | } 35 | 36 | for (let i = 1; i < m; i++) { 37 | for (let j = 1; j < n; j++) { 38 | path[i][j] = Math.min(path[i - 1][j], path[i][j - 1]) + grid[i][j]; 39 | } 40 | } 41 | 42 | return path[m - 1][n - 1]; 43 | }; 44 | // @lc code=end 45 | -------------------------------------------------------------------------------- /动态规划/647.回文子串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=647 lang=javascript 3 | * 4 | * [647] 回文子串 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {number} 11 | */ 12 | var countSubstrings = function (s) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(MN) 17 | * @spaceComplexity O(MN) 18 | */ 19 | const length = s.length; 20 | const path = new Array(length) 21 | .fill() 22 | .map(() => new Array(length).fill(false)); 23 | 24 | let result = 0; 25 | for (let i = length - 1; i >= 0; i--) { 26 | for (let j = i; j < length; j++) { 27 | if (s[i] === s[j] && (j - i <= 1 || path[i + 1][j - 1])) { 28 | result++; 29 | path[i][j] = true; 30 | } 31 | } 32 | } 33 | return result; 34 | }; 35 | // @lc code=end 36 | -------------------------------------------------------------------------------- /动态规划/70.爬楼梯.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=70 lang=javascript 3 | * 4 | * [70] 爬楼梯 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} n 10 | * @return {number} 11 | */ 12 | var climbStairs = function (n) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | // let p = 0; 20 | // let q = 0; 21 | // let r = 1; 22 | // for (let i = 1; i <= n; i++) { 23 | // p = q; 24 | // q = r; 25 | // r = p + q; 26 | // } 27 | // return r; 28 | 29 | // 通项公式 30 | const sqrt5 = Math.sqrt(5); 31 | const fib = 32 | Math.pow((1 + sqrt5) / 2, n + 1) - Math.pow((1 - sqrt5) / 2, n + 1); 33 | return Math.round(fib / sqrt5); 34 | }; 35 | // @lc code=end 36 | -------------------------------------------------------------------------------- /动态规划/718.最长重复子数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=718 lang=javascript 3 | * 4 | * [718] 最长重复子数组 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums1 10 | * @param {number[]} nums2 11 | * @return {number} 12 | */ 13 | var findLength = function (nums1, nums2) { 14 | /** 15 | * @author xun 16 | * @method 动态规划 17 | * @timeComplexity O(M * N) 18 | * @spaceComplexity O(N) 19 | */ 20 | const m = nums1.length; 21 | const n = nums2.length; 22 | 23 | const path = new Array(n + 1).fill(0); 24 | let res = 0; 25 | 26 | for (let i = 1; i <= m; i++) { 27 | for (let j = n; j >= 1; j--) { 28 | if (nums1[i - 1] === nums2[j - 1]) path[j] = path[j - 1] + 1; 29 | else path[j] = 0; 30 | 31 | res = Math.max(path[j], res); 32 | } 33 | } 34 | 35 | return res; 36 | }; 37 | // @lc code=end 38 | -------------------------------------------------------------------------------- /动态规划/72.编辑距离.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=72 lang=javascript 3 | * 4 | * [72] 编辑距离 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} word1 10 | * @param {string} word2 11 | * @return {number} 12 | */ 13 | var minDistance = function (word1, word2) { 14 | /** 15 | * @author xun 16 | * @method 动态规划 17 | * @timeComplexity O(mn) 18 | * @spaceComplexity O(mn) 19 | */ 20 | const m = word1.length; 21 | const n = word2.length; 22 | 23 | const path = new Array(m + 1).fill().map(() => new Array(n + 1).fill(0)); 24 | 25 | for (let i = 0; i <= m; i++) path[i][0] = i; 26 | for (let i = 0; i <= n; i++) path[0][i] = i; 27 | 28 | for (let i = 1; i <= m; i++) { 29 | for (let j = 1; j <= n; j++) { 30 | if (word1[i - 1] === word2[j - 1]) { 31 | path[i][j] = path[i - 1][j - 1]; 32 | } else { 33 | path[i][j] = 34 | Math.min(path[i - 1][j], path[i][j - 1], path[i - 1][j - 1]) + 1; 35 | } 36 | } 37 | } 38 | return path[m][n]; 39 | }; 40 | // @lc code=end 41 | -------------------------------------------------------------------------------- /动态规划/746.使用最小花费爬楼梯.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=746 lang=javascript 3 | * 4 | * [746] 使用最小花费爬楼梯 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} cost 10 | * @return {number} 11 | */ 12 | var minCostClimbingStairs = function (cost) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const length = cost.length; 20 | 21 | let previous = 0; 22 | let current = 0; 23 | for (let i = 2; i <= length; i++) { 24 | let next = Math.min(current + cost[i - 1], previous + cost[i - 2]); 25 | previous = current; 26 | current = next; 27 | } 28 | return current; 29 | }; 30 | // @lc code=end 31 | -------------------------------------------------------------------------------- /双指针/11.盛最多水的容器.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=11 lang=javascript 3 | * 4 | * [11] 盛最多水的容器 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} height 10 | * @return {number} 11 | */ 12 | var maxArea = function (height) { 13 | /** 14 | * @author xun 15 | * @method 双指针 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let result = 0; 20 | let vol = 0; 21 | 22 | let left = 0; 23 | let right = height.length - 1; 24 | 25 | while (left < right) { 26 | // 长 * 宽 (最小的宽) 27 | vol = (right - left) * Math.min(height[left], height[right]); 28 | 29 | result = Math.max(result, vol); 30 | 31 | if (height[left] <= height[right]) left++; 32 | else right--; 33 | } 34 | 35 | return result; 36 | }; 37 | // @lc code=end 38 | -------------------------------------------------------------------------------- /双指针/125.验证回文串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=125 lang=javascript 3 | * 4 | * [125] 验证回文串 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {boolean} 11 | */ 12 | var isPalindrome = function (s) { 13 | /** 14 | * @author xun 15 | * @method 双指针 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const str = s.replace(/[^a-z0-9]/gi, "").toLocaleLowerCase(); 20 | 21 | let left = 0; 22 | let right = str.length - 1; 23 | 24 | while (left <= right) { 25 | if (str[left] !== str[right]) { 26 | return false; 27 | } 28 | left++; 29 | right--; 30 | } 31 | return true; 32 | }; 33 | // @lc code=end 34 | -------------------------------------------------------------------------------- /双指针/15.三数之和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=15 lang=javascript 3 | * 4 | * [15] 三数之和 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number[][]} 11 | */ 12 | var threeSum = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 排序+双指针 16 | * @timeComplexity O(N*N) 17 | * @spaceComplexity O(log N) 18 | */ 19 | const result = []; 20 | const length = nums.length; 21 | 22 | nums.sort((a, b) => a - b); 23 | 24 | for (let i = 0; i < length; i++) { 25 | if (nums[i] === nums[i - 1]) continue; 26 | 27 | let left = i + 1; 28 | let right = length - 1; 29 | 30 | while (left < right) { 31 | if (right === i) right--; 32 | else if (nums[left] + nums[right] + nums[i] === 0) { 33 | // 命中 34 | result.push([nums[left], nums[right], nums[i]]); 35 | 36 | while (nums[left] === nums[left + 1]) left++; 37 | left++; 38 | 39 | while (nums[right] === nums[right - 1]) right--; 40 | right--; 41 | } else if (nums[left] + nums[right] + nums[i] > 0) right--; 42 | else left++; 43 | } 44 | } 45 | 46 | return result; 47 | }; 48 | // @lc code=end 49 | -------------------------------------------------------------------------------- /双指针/16.最接近的三数之和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=16 lang=javascript 3 | * 4 | * [16] 最接近的三数之和 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @param {number} target 11 | * @return {number} 12 | */ 13 | var threeSumClosest = function (nums, target) { 14 | /** 15 | * @author xun 16 | * @method 排序+双指针 17 | * @timeComplexity O(N*N) 18 | * @spaceComplexity O(log N) 19 | */ 20 | nums.sort((a, b) => a - b); 21 | const length = nums.length; 22 | 23 | if (length < 3) return; 24 | 25 | let min = +Infinity; 26 | let sum = 0; 27 | 28 | for (let i = 0; i < length - 2; i++) { 29 | let n1 = nums[i]; 30 | let left = i + 1; 31 | let right = length - 1; 32 | 33 | while (left < right) { 34 | let n2 = nums[left]; 35 | let n3 = nums[right]; 36 | let result = n1 + n2 + n3 - target; //差值 37 | if (min > Math.abs(result)) { 38 | min = Math.abs(result); 39 | sum = n1 + n2 + n3; 40 | } 41 | 42 | if (result >= 0) right--; 43 | else left++; 44 | } 45 | } 46 | 47 | return sum; 48 | }; 49 | // @lc code=end 50 | -------------------------------------------------------------------------------- /双指针/165.比较版本号.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=165 lang=javascript 3 | * 4 | * [165] 比较版本号 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} version1 10 | * @param {string} version2 11 | * @return {number} 12 | */ 13 | var compareVersion = function (version1, version2) { 14 | /** 15 | * @author xun 16 | * @method 双指针 17 | * @timeComplexity O(M + N) 18 | * @spaceComplexity O(1) 19 | */ 20 | const m = version1.length; 21 | const n = version2.length; 22 | 23 | let i = 0; 24 | let j = 0; 25 | 26 | while (i < m || j < n) { 27 | let x = 0; 28 | let y = 0; 29 | 30 | while (i < m && version1[i] !== ".") { 31 | x = x * 10 + version1[i] - "0"; 32 | i++; 33 | } 34 | i++; 35 | 36 | while (j < n && version2[j] !== ".") { 37 | y = y * 10 + version2[j] - "0"; 38 | j++; 39 | } 40 | j++; 41 | 42 | if (x !== y) return x > y ? 1 : -1; 43 | } 44 | 45 | return 0; 46 | }; 47 | // @lc code=end 48 | -------------------------------------------------------------------------------- /双指针/167.两数之和-ii-输入有序数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=167 lang=javascript 3 | * 4 | * [167] 两数之和 II - 输入有序数组 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} numbers 10 | * @param {number} target 11 | * @return {number[]} 12 | */ 13 | var twoSum = function (numbers, target) { 14 | /** 15 | * @author xun 16 | * @method 双指针 17 | * @timeComplexity O(N) 18 | * @spaceComplexity O(1) 19 | */ 20 | if (!numbers) return numbers; 21 | let left = 0; 22 | let right = numbers.length - 1; 23 | 24 | while (left < right) { 25 | const sum = numbers[left] + numbers[right]; 26 | 27 | if (sum === target) return [left + 1, right + 1]; 28 | else if (sum > target) right--; 29 | else left++; 30 | } 31 | return numbers; 32 | }; 33 | // @lc code=end 34 | -------------------------------------------------------------------------------- /双指针/202.快乐数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=202 lang=javascript 3 | * 4 | * [202] 快乐数 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} n 10 | * @return {boolean} 11 | */ 12 | var isHappy = function (n) { 13 | /** 14 | * @author xun 15 | * @method 快慢指针 16 | * @timeComplexity O(log N) 17 | * @spaceComplexity O(1) 18 | */ 19 | function squareSum(n) { 20 | let sum = 0; 21 | while (n > 0) { 22 | let digit = n % 10; 23 | sum += digit * digit; 24 | n = Math.floor(n / 10); 25 | } 26 | return sum; 27 | } 28 | let slow = n; 29 | let fast = squareSum(n); 30 | 31 | while (slow !== fast) { 32 | slow = squareSum(slow); 33 | fast = squareSum(squareSum(fast)); 34 | } 35 | 36 | return slow === 1; 37 | }; 38 | // @lc code=end 39 | -------------------------------------------------------------------------------- /双指针/209.长度最小的子数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=209 lang=javascript 3 | * 4 | * [209] 长度最小的子数组 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} target 10 | * @param {number[]} nums 11 | * @return {number} 12 | */ 13 | // [2, 3, 1, 2, 4, 3]; 7 14 | var minSubArrayLen = function (target, nums) { 15 | /** 16 | * @author xun 17 | * @method 滑动窗口 18 | * @timeComplexity O(N) 19 | * @spaceComplexity O(1) 20 | */ 21 | const length = nums.length; 22 | 23 | let ans = Infinity; 24 | let left = 0; 25 | let right = 0; 26 | let sum = 0; 27 | 28 | while (right < length) { 29 | sum += nums[right]; 30 | 31 | while (sum >= target) { 32 | ans = Math.min(ans, right - left + 1); 33 | sum -= nums[left]; 34 | left++; 35 | } 36 | right++; 37 | } 38 | return ans === Infinity ? 0 : ans; 39 | }; 40 | 41 | // @lc code=end 42 | -------------------------------------------------------------------------------- /双指针/26.删除有序数组中的重复项.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=26 lang=javascript 3 | * 4 | * [26] 删除有序数组中的重复项 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var removeDuplicates = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 快慢指针 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const length = nums.length; 20 | 21 | if (length === 0) return 0; 22 | 23 | let fast = 1; 24 | let slow = 1; 25 | 26 | while (fast < length) { 27 | if (nums[fast] !== nums[fast - 1]) { 28 | nums[slow] = nums[fast]; 29 | ++slow; 30 | } 31 | ++fast; 32 | } 33 | 34 | return slow; 35 | }; 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /双指针/27.移除元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=27 lang=javascript 3 | * 4 | * [27] 移除元素 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @param {number} val 11 | * @return {number} 12 | */ 13 | var removeElement = function (nums, val) { 14 | /** 15 | * @author xun 16 | * @method 双指针 17 | * @timeComplexity O(N) 18 | * @spaceComplexity O(1) 19 | */ 20 | let left = 0; 21 | let right = nums.length; 22 | 23 | while (left < right) { 24 | if (nums[left] === val) nums[left] = nums[--right]; 25 | else left++; 26 | } 27 | return left; 28 | }; 29 | 30 | // @lc code=end 31 | -------------------------------------------------------------------------------- /双指针/283.移动零.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=283 lang=javascript 3 | * 4 | * [283] 移动零 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {void} Do not return anything, modify nums in-place instead. 11 | */ 12 | 13 | // [0,1,0,3,12] 14 | // [1,3,12,0,0] 15 | var moveZeroes = function (nums) { 16 | /** 17 | * @author xun 18 | * @method 双指针 19 | * @timeComplexity O(N) 20 | * @spaceComplexity O(1) 21 | */ 22 | let left = 0; 23 | let right = 0; 24 | const n = nums.length; 25 | 26 | while (right < n) { 27 | if (nums[right]) { 28 | [nums[left], nums[right]] = [nums[right], nums[left]]; 29 | left++; 30 | } 31 | right++; 32 | } 33 | return nums; 34 | }; 35 | // @lc code=end 36 | -------------------------------------------------------------------------------- /双指针/287.寻找重复数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=287 lang=javascript 3 | * 4 | * [287] 寻找重复数 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var findDuplicate = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 快慢指针 16 | * @timeComplexity O(n)) 17 | * @spaceComplexity O(1) 18 | */ 19 | let slow = nums[0]; 20 | let fast = nums[nums[0]]; 21 | `` 22 | // 第一次相遇 23 | while (slow !== fast) { 24 | slow = nums[slow]; 25 | fast = nums[nums[fast]]; 26 | } 27 | 28 | slow = 0; 29 | while (slow !== fast) { 30 | slow = nums[slow]; 31 | fast = nums[fast]; 32 | } 33 | 34 | return slow; 35 | }; 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /双指针/3.无重复字符的最长子串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=3 lang=javascript 3 | * 4 | * [3] 无重复字符的最长子串 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {number} 11 | */ 12 | var lengthOfLongestSubstring = function (s) { 13 | /** 14 | * @author xun 15 | * @method 滑动窗口 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(E) 18 | */ 19 | let left = 0; 20 | let result = 0; 21 | let right = 0; 22 | const n = s.length; 23 | const map = new Map(); 24 | 25 | while (right < n) { 26 | const char = s[right]; 27 | if (map.has(char) && map.get(char) >= left) { 28 | left = map.get(char) + 1; 29 | } 30 | result = Math.max(result, right - left + 1); 31 | map.set(char, right); 32 | right++; 33 | } 34 | return result; 35 | }; 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /双指针/344.反转字符串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=344 lang=javascript 3 | * 4 | * [344] 反转字符串 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {character[]} s 10 | * @return {void} Do not return anything, modify s in-place instead. 11 | */ 12 | var reverseString = function (s) { 13 | /** 14 | * @author xun 15 | * @method 双指针 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let first = 0; 20 | let last = s.length - 1; 21 | 22 | while (first < last) { 23 | [s[first], s[last]] = [s[last], s[first]]; 24 | first++; 25 | last--; 26 | } 27 | }; 28 | // @lc code=end 29 | -------------------------------------------------------------------------------- /双指针/349.两个数组的交集.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=349 lang=javascript 3 | * 4 | * [349] 两个数组的交集 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums1 10 | * @param {number[]} nums2 11 | * @return {number[]} 12 | */ 13 | var intersection = function (nums1, nums2) { 14 | /** 15 | * @author xun 16 | * @method 两个集合 17 | * @timeComplexity O(M + N) 18 | * @spaceComplexity O(M + N) 19 | */ 20 | const result = new Set(); 21 | const set = new Set(nums2); 22 | 23 | for (const num of nums1) { 24 | if (set.has(num)) { 25 | result.add(num); 26 | } 27 | } 28 | 29 | return Array.from(result); 30 | }; 31 | // @lc code=end 32 | -------------------------------------------------------------------------------- /双指针/350.两个数组的交集-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=350 lang=javascript 3 | * 4 | * [350] 两个数组的交集 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums1 10 | * @param {number[]} nums2 11 | * @return {number[]} 12 | */ 13 | var intersect = function (nums1, nums2) { 14 | /** 15 | * @author xun 16 | * @method 排序+双指针 17 | * @timeComplexity O(m log(m) + n log(n)) 18 | * @spaceComplexity O(min(m,n)) 19 | */ 20 | nums1.sort((a, b) => a - b); 21 | nums2.sort((a, b) => a - b); 22 | 23 | const result = []; 24 | let i = 0; 25 | let j = 0; 26 | 27 | while (i < nums1.length && j < nums2.length) { 28 | if (nums1[i] === nums2[j]) { 29 | result.push(nums1[i]); 30 | i++; 31 | j++; 32 | } else { 33 | nums1[i] < nums2[j] ? i++ : j++; 34 | } 35 | } 36 | return result; 37 | }; 38 | // @lc code=end 39 | -------------------------------------------------------------------------------- /双指针/4.寻找两个正序数组的中位数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=4 lang=javascript 3 | * 4 | * [4] 寻找两个正序数组的中位数 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums1 10 | * @param {number[]} nums2 11 | * @return {number} 12 | */ 13 | var findMedianSortedArrays = function (nums1, nums2) { 14 | /** 15 | * @author xun 16 | * @method 双指针 17 | * @timeComplexity O(N) 18 | * @spaceComplexity O(1) 19 | */ 20 | const num1_length = nums1.length; 21 | const num2_length = nums2.length; 22 | const length = num1_length + num2_length; 23 | 24 | let previousValue = -1; 25 | let currentValue = -1; 26 | let point1 = 0; 27 | let point2 = 0; 28 | 29 | // 双指针直接遍历,向后移动 30 | // 双指针直接遍历,向后移动 31 | for (let i = 0; i <= Math.floor(length / 2); i++) { 32 | previousValue = currentValue; 33 | if ( 34 | point1 < num1_length && 35 | (point2 >= num2_length || nums1[point1] < nums2[point2]) 36 | ) 37 | currentValue = nums1[point1++]; 38 | else currentValue = nums2[point2++]; 39 | } 40 | 41 | // 长度为单数的情况 42 | if (length % 2 === 0) return (previousValue + currentValue) / 2.0; 43 | else return currentValue; 44 | }; 45 | // @lc code=end 46 | -------------------------------------------------------------------------------- /双指针/443.压缩字符串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=443 lang=javascript 3 | * 4 | * [443] 压缩字符串 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {character[]} chars 10 | * @return {number} 11 | */ 12 | var compress = function (chars) { 13 | /** 14 | * @author xun 15 | * @method 双指针 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let write = 0; // 用于写入压缩结果的位置 20 | let i = 0; // 用于遍历数组的指针 21 | 22 | while (i < chars.length) { 23 | let j = i; 24 | // 计算相同字符的长度 25 | while (j < chars.length && chars[i] === chars[j]) { 26 | j++; 27 | } 28 | // 计算字符重复的次数 29 | const count = j - i; 30 | // 写入字符 31 | chars[write++] = chars[i]; 32 | // 如果字符重复次数大于1,则写入重复次数 33 | if (count > 1) { 34 | for (const c of count.toString()) { 35 | chars[write++] = c; 36 | } 37 | } 38 | // 移动到下一个不同的字符 39 | i = j; 40 | } 41 | 42 | // 返回压缩后的长度 43 | return write; 44 | }; 45 | 46 | // @lc code=end 47 | -------------------------------------------------------------------------------- /双指针/455.分发饼干.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=455 lang=javascript 3 | * 4 | * [455] 分发饼干 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} g 10 | * @param {number[]} s 11 | * @return {number} 12 | */ 13 | var findContentChildren = function (g, s) { 14 | /** 15 | * @author xun 16 | * @method 双指针 17 | * @timeComplexity O(m log m+n log n) 18 | * @spaceComplexity O(m log m+n log n) 19 | */ 20 | g.sort((a, b) => a - b); 21 | s.sort((a, b) => a - b); 22 | 23 | const n = s.length; 24 | let count = 0; 25 | let index = 0; 26 | 27 | for (let i = 0; i < n; i++) { 28 | if (s[i] >= g[index]) { 29 | count++; 30 | index++; 31 | } 32 | } 33 | 34 | return count; 35 | }; 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /双指针/5.最长回文子串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=5 lang=javascript 3 | * 4 | * [5] 最长回文子串 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {string} 11 | */ 12 | var longestPalindrome = function (s) { 13 | /** 14 | * @author xun 15 | * @method 双指针 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const length = s.length; 20 | if (length < 2) return s; 21 | 22 | let max = ""; 23 | 24 | for (let i = 0; i < length; i++) { 25 | helper(i, i); 26 | helper(i, i + 1); 27 | } 28 | 29 | function helper(left, right) { 30 | while (left >= 0 && right < length && s[left] === s[right]) { 31 | right++; 32 | left--; 33 | } 34 | const maxStr = s.slice(left + 1, right); 35 | 36 | if (maxStr.length > max.length) max = maxStr; 37 | } 38 | 39 | return max; 40 | }; 41 | // @lc code=end 42 | -------------------------------------------------------------------------------- /双指针/581.最短无序连续子数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=581 lang=javascript 3 | * 4 | * [581] 最短无序连续子数组 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var findUnsortedSubarray = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 双指针 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const n = nums.length; 20 | let max = -Number.MAX_VALUE; 21 | let min = Number.MAX_VALUE; 22 | let left = -1; 23 | let right = -1; 24 | 25 | for (let i = 0; i < n; i++) { 26 | if (max > nums[i]) { 27 | right = i; 28 | } else { 29 | max = nums[i]; 30 | } 31 | 32 | if (min < nums[n - i - 1]) { 33 | left = n - i - 1; 34 | } else { 35 | min = nums[n - i - 1]; 36 | } 37 | } 38 | 39 | return right === -1 ? 0 : right - left + 1; 40 | }; 41 | // @lc code=end 42 | -------------------------------------------------------------------------------- /双指针/75.颜色分类.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=75 lang=javascript 3 | * 4 | * [75] 颜色分类 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {void} Do not return anything, modify nums in-place instead. 11 | */ 12 | var sortColors = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 双指针 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const n = nums.length; 20 | 21 | let left = 0; 22 | let right = n - 1; 23 | 24 | for (let i = 0; i <= right; i++) { 25 | while (i < right && nums[i] === 2) { 26 | [nums[i], nums[right]] = [nums[right], nums[i]]; 27 | right--; 28 | } 29 | 30 | if (nums[i] === 0) { 31 | [nums[i], nums[left]] = [nums[left], nums[i]]; 32 | left++; 33 | } 34 | } 35 | }; 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /双指针/80.删除有序数组中的重复项-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=80 lang=javascript 3 | * 4 | * [80] 删除有序数组中的重复项 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var removeDuplicates = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 双指针 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const n = nums.length; 20 | 21 | if (n <= 2) return n; 22 | 23 | let slow = 2; 24 | let fast = 2; 25 | 26 | while (fast < n) { 27 | if (nums[slow - 2] !== nums[fast]) { 28 | nums[slow] = nums[fast]; 29 | slow++; 30 | } 31 | fast++; 32 | } 33 | return slow; 34 | }; 35 | 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /双指针/844.比较含退格的字符串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=844 lang=javascript 3 | * 4 | * [844] 比较含退格的字符串 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @param {string} t 11 | * @return {boolean} 12 | */ 13 | var backspaceCompare = function (s, t) { 14 | let i = s.length - 1; 15 | let j = t.length - 1; 16 | let backSpaceS = 0; 17 | let backSpaceT = 0; 18 | 19 | while (i >= 0 || j >= 0) { 20 | // s 循环 21 | while (i >= 0) { 22 | if (s[i] === "#") { 23 | backSpaceS++; 24 | i--; 25 | } else if (backSpaceS > 0) { 26 | backSpaceS--; 27 | i--; 28 | } else break; 29 | } 30 | 31 | // t 循环 32 | while (j >= 0) { 33 | if (t[j] === "#") { 34 | backSpaceT++; 35 | j--; 36 | } else if (backSpaceT > 0) { 37 | backSpaceT--; 38 | j--; 39 | } else break; 40 | } 41 | if (s[i] !== t[j]) return false; 42 | i--; 43 | j--; 44 | } 45 | return true; 46 | }; 47 | // @lc code=end 48 | -------------------------------------------------------------------------------- /双指针/88.合并两个有序数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=88 lang=javascript 3 | * 4 | * [88] 合并两个有序数组 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums1 10 | * @param {number} m 11 | * @param {number[]} nums2 12 | * @param {number} n 13 | * @return {void} Do not return anything, modify nums1 in-place instead. 14 | */ 15 | var merge = function (nums1, m, nums2, n) { 16 | /** 17 | * @author xun 18 | * @method 暴力破解 19 | * @timeComplexity O(m+n) 20 | * @spaceComplexity O(log(m+n)) 21 | */ 22 | // nums1.splice(m, nums1.length - m, ...nums2); 23 | // nums1.sort((a, b) => a - b); 24 | /** 25 | * @author xun 26 | * @method 双指针 27 | * @timeComplexity O(N) 28 | * @spaceComplexity O(1) 29 | */ 30 | let p1 = m - 1; 31 | let p2 = n - 1; 32 | 33 | let current = 0; 34 | let tail = m + n - 1; 35 | 36 | while (p1 >= 0 || p2 >= 0) { 37 | if (p1 === -1) { 38 | current = nums2[p2--]; 39 | } else if (p2 === -1) { 40 | current = nums1[p1--]; 41 | } else if (nums1[p1] > nums2[p2]) { 42 | current = nums1[p1--]; 43 | } else { 44 | current = nums2[p2--]; 45 | } 46 | nums1[tail--] = current; 47 | } 48 | }; 49 | // @lc code=end 50 | -------------------------------------------------------------------------------- /双指针/905.按奇偶排序数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=905 lang=javascript 3 | * 4 | * [905] 按奇偶排序数组 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number[]} 11 | */ 12 | var sortArrayByParity = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 双指针 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const length = nums.length; 20 | const result = new Array(length).fill(0); 21 | 22 | let lef = 0; 23 | let right = length - 1; 24 | 25 | for (const num of nums) { 26 | if (num % 2 === 0) result[lef++] = num; 27 | else result[right--] = num; 28 | } 29 | 30 | return result; 31 | }; 32 | // @lc code=end 33 | -------------------------------------------------------------------------------- /双指针/977.有序数组的平方.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=977 lang=javascript 3 | * 4 | * [977] 有序数组的平方 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number[]} 11 | */ 12 | var sortedSquares = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 双指针 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(N) 18 | */ 19 | let left = 0; 20 | let right = nums.length - 1; 21 | const n = right; 22 | const result = new Array(n + 1); 23 | 24 | for (let i = 0; i <= n; i++) { 25 | const rightAbs = nums[right] * nums[right]; 26 | const leftAbs = nums[left] * nums[left]; 27 | if (leftAbs > rightAbs) { 28 | result[n - i] = leftAbs; 29 | left++; 30 | } else { 31 | result[n - i] = rightAbs; 32 | right--; 33 | } 34 | } 35 | 36 | return result; 37 | }; 38 | // @lc code=end 39 | -------------------------------------------------------------------------------- /哈希表/1.两数之和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1 lang=javascript 3 | * 4 | * [1] 两数之和 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @param {number} target 11 | * @return {number[]} 12 | */ 13 | var twoSum = function (nums, target) { 14 | /** 15 | * @author xun 16 | * @method 暴力破解 17 | * @timeComplexity O(N*N) 18 | * @spaceComplexity O(1) 19 | */ 20 | // const length = nums.length; 21 | // for (let i = 0; i < length; i++) { 22 | // for (let j = 0; j < length; j++) { 23 | // if (nums[i] + nums[j] === target && i !== j) { 24 | // return [i, j]; 25 | // } 26 | // } 27 | // } 28 | /** 29 | * @author xun 30 | * @method 哈希表 31 | * @timeComplexity O(N) 32 | * @spaceComplexity O(N) 33 | */ 34 | const map = new Map(); 35 | for (let i = 0; i < nums.length; i++) { 36 | let num = target - nums[i]; 37 | 38 | if (map.has(num)) { 39 | return [map.get(num), i]; 40 | } else { 41 | map.set(nums[i], i); 42 | } 43 | } 44 | }; 45 | // @lc code=end 46 | -------------------------------------------------------------------------------- /哈希表/128.最长连续序列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=128 lang=javascript 3 | * 4 | * [128] 最长连续序列 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var longestConsecutive = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 哈希表 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(N) 18 | */ 19 | const set = new Set(nums); 20 | 21 | let n = 0; 22 | 23 | for (const num of set) { 24 | if (!set.has(num - 1)) { 25 | let currentNum = num; 26 | let currentStreak = 1; 27 | 28 | while (set.has(currentNum + 1)) { 29 | currentNum += 1; 30 | currentStreak += 1; 31 | } 32 | 33 | n = Math.max(n, currentStreak); 34 | } 35 | } 36 | 37 | return n; 38 | }; 39 | // @lc code=end 40 | -------------------------------------------------------------------------------- /哈希表/1287.有序数组中出现次数超过-25-的元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1287 lang=javascript 3 | * 4 | * [1287] 有序数组中出现次数超过25%的元素 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} arr 10 | * @return {number} 11 | */ 12 | var findSpecialInteger = function (arr) { 13 | /** 14 | * @author xun 15 | * @method 哈希表 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const map = new Map(); 20 | 21 | arr.forEach((item) => map.set(item, map.has(item) ? map.get(item) + 1 : 1)); 22 | for (const [key, value] of map) { 23 | if (value > arr.length / 4) return key; 24 | } 25 | }; 26 | // @lc code=end 27 | -------------------------------------------------------------------------------- /哈希表/137.只出现一次的数字-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=137 lang=javascript 3 | * 4 | * [137] 只出现一次的数字 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var singleNumber = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 哈希表 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(N) 18 | */ 19 | const map = new Map(); 20 | 21 | for (const num of nums) { 22 | map.set(num, (map.get(num) || 0) + 1); 23 | } 24 | 25 | let result = 0; 26 | for (const [key, value] of map.entries()) { 27 | if (value === 1) return (result = key); 28 | } 29 | }; 30 | // @lc code=end 31 | -------------------------------------------------------------------------------- /哈希表/187.重复的dna序列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=187 lang=javascript 3 | * 4 | * [187] 重复的DNA序列 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {string[]} 11 | */ 12 | var findRepeatedDnaSequences = function (s) { 13 | /** 14 | * @author xun 15 | * @method 哈希表 16 | * @timeComplexity O(NL) 17 | * @spaceComplexity O(NL) 18 | */ 19 | const n = 10; 20 | const ans = []; 21 | const map = new Map(); 22 | 23 | const length = s.length; 24 | 25 | for (let i = 0; i <= length - n; i++) { 26 | const sub = s.slice(i, i + n); 27 | const count = (map.get(sub) || 0) + 1; 28 | map.set(sub, count); 29 | 30 | if (count === 2) ans.push(sub); 31 | } 32 | 33 | return ans; 34 | }; 35 | // @lc code=end 36 | -------------------------------------------------------------------------------- /哈希表/205.同构字符串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=205 lang=javascript 3 | * 4 | * [205] 同构字符串 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @param {string} t 11 | * @return {boolean} 12 | */ 13 | var isIsomorphic = function (s, t) { 14 | /** 15 | * @author xun 16 | * @method 哈希表 17 | * @timeComplexity O(N) 18 | * @spaceComplexity O(∣Σ∣) 19 | */ 20 | const s2t = new Map(); 21 | const t2s = new Map(); 22 | const length = s.length; 23 | 24 | for (let i = 0; i < length; i++) { 25 | const x = s[i]; 26 | const y = t[i]; 27 | 28 | // 合并判断条件,检查s到t和t到s的映射是否一致 29 | if ((s2t.has(x) && s2t.get(x) !== y) || (t2s.has(y) && t2s.get(y) !== x)) { 30 | return false; 31 | } 32 | 33 | s2t.set(x, y); 34 | t2s.set(y, x); 35 | } 36 | 37 | return true; 38 | }; 39 | // @lc code=end 40 | -------------------------------------------------------------------------------- /哈希表/217.存在重复元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=217 lang=javascript 3 | * 4 | * [217] 存在重复元素 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {boolean} 11 | */ 12 | var containsDuplicate = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 哈希表 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(N) 18 | */ 19 | const set = new Set(); 20 | 21 | for (const number of nums) { 22 | if (set.has(number)) return true; 23 | else set.add(number); 24 | } 25 | return false; 26 | }; 27 | // @lc code=end 28 | -------------------------------------------------------------------------------- /哈希表/242.有效的字母异位词.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=242 lang=javascript 3 | * 4 | * [242] 有效的字母异位词 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @param {string} t 11 | * @return {boolean} 12 | */ 13 | var isAnagram = function (s, t) { 14 | if (s.length !== t.length) return false; 15 | 16 | const table = new Array(26).fill(0); 17 | 18 | for (let i = 0; i < s.length; i++) { 19 | table[s.codePointAt(i) - "a".codePointAt(0)]++; 20 | } 21 | 22 | for (let i = 0; i < t.length; i++) { 23 | table[t.codePointAt(i) - "a".codePointAt(0)]--; 24 | if (table[t.codePointAt(i) - "a".codePointAt(0)] < 0) return false; 25 | } 26 | 27 | return true; 28 | }; 29 | // @lc code=end 30 | -------------------------------------------------------------------------------- /哈希表/2744.最大字符串配对数目.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=2744 lang=javascript 3 | * 4 | * [2744] 最大字符串配对数目 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string[]} words 10 | * @return {number} 11 | */ 12 | var maximumNumberOfStringPairs = function (words) { 13 | /** 14 | * @author xun 15 | * @method 哈希表 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(N) 18 | */ 19 | const n = words.length; 20 | const seen = new Set(); 21 | 22 | let ans = 0; 23 | 24 | for (const word of words) { 25 | if (seen.has(word.charCodeAt(1) * 100 + word.charCodeAt(0))) { 26 | ans++; 27 | } 28 | seen.add(word.charCodeAt(0) * 100 + word.charCodeAt(1)); 29 | } 30 | 31 | return ans; 32 | }; 33 | // @lc code=end 34 | -------------------------------------------------------------------------------- /哈希表/347.前-k-个高频元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=347 lang=javascript 3 | * 4 | * [347] 前 K 个高频元素 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @param {number} k 11 | * @return {number[]} 12 | */ 13 | var topKFrequent = function (nums, k) { 14 | /** 15 | * @author xun 16 | * @method 哈希表 17 | * @timeComplexity O(N) 18 | * @spaceComplexity O(N) 19 | */ 20 | const result = []; 21 | const map = new Map(); 22 | 23 | for (const num of nums) { 24 | if (map.has(num)) map.set(num, map.get(num) + 1); 25 | else map.set(num, 1); 26 | } 27 | 28 | const m = new Map([...map].sort((a, b) => b[1] - a[1])); 29 | 30 | for (let i = 0; i < k; i++) { 31 | result[i] = [...m][i][0]; 32 | } 33 | 34 | return result; 35 | }; 36 | 37 | // @lc code=end 38 | -------------------------------------------------------------------------------- /哈希表/387.字符串中的第一个唯一字符.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=387 lang=javascript 3 | * 4 | * [387] 字符串中的第一个唯一字符 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {number} 11 | */ 12 | var firstUniqChar = function (s) { 13 | /** 14 | * @author xun 15 | * @method 哈希表 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(∣Σ∣) 18 | */ 19 | const position = new Map(); 20 | const length = s.length; 21 | 22 | for (const [index, char] of Array.from(s).entries()) { 23 | if (position.has(char)) position.set(char, -1); 24 | else position.set(char, index); 25 | } 26 | 27 | let first = length; 28 | 29 | for (const pos of position.values()) { 30 | if (pos !== -1 && pos < first) first = pos; 31 | } 32 | 33 | return first === length ? -1 : first; 34 | }; 35 | // @lc code=end 36 | -------------------------------------------------------------------------------- /哈希表/41.缺失的第一个正数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=41 lang=javascript 3 | * 4 | * [41] 缺失的第一个正数 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var firstMissingPositive = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 哈希表 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | 20 | if (nums.length === 0) return 1; 21 | if (nums.length === 1 && nums[0] <= 0) return 1; 22 | 23 | const arr = []; 24 | 25 | for (const value of nums) { 26 | if (value >= 1) { 27 | arr[value] = 1; 28 | } 29 | } 30 | 31 | if (!arr.length) return 1; 32 | 33 | for (let i = 1; i < arr.length; i++) { 34 | if (!arr[i]) { 35 | return i; 36 | } 37 | } 38 | 39 | return arr.length; 40 | }; 41 | // @lc code=end 42 | -------------------------------------------------------------------------------- /回溯/22.括号生成.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=22 lang=javascript 3 | * 4 | * [22] 括号生成 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} n 10 | * @return {string[]} 11 | */ 12 | var generateParenthesis = function (n) { 13 | /** 14 | * @author xun 15 | * @method 回溯 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(N) 18 | */ 19 | if (n === 0) return []; 20 | 21 | const result = []; 22 | 23 | function dfs(left, right, str) { 24 | if (str.length === 2 * n) { 25 | result.push(str); 26 | return; 27 | } 28 | 29 | // 选择左括号,只要 ( 有剩余就选择 30 | if (left > 0) dfs(left - 1, right, str + "("); 31 | 32 | // 选择又括号,只有右括号的数量大于左括号才能炫 33 | if (left < right) dfs(left, right - 1, str + ")"); 34 | } 35 | 36 | dfs(n, n, ""); 37 | return result; 38 | }; 39 | // @lc code=end 40 | -------------------------------------------------------------------------------- /回溯/39.组合总和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=39 lang=javascript 3 | * 4 | * [39] 组合总和 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} candidates 10 | * @param {number} target 11 | * @return {number[][]} 12 | */ 13 | var combinationSum = function (candidates, target) { 14 | /** 15 | * @author xun 16 | * @method 搜索回溯 17 | * @timeComplexity O(S) 18 | * @spaceComplexity O(target) 19 | */ 20 | const result = []; 21 | function dfs(target, combine, index) { 22 | if (index === candidates.length) return; 23 | 24 | if (target === 0) { 25 | result.push(combine); 26 | // 跳出当前的函数栈 27 | return; 28 | } 29 | 30 | dfs(target, combine, index + 1); 31 | 32 | if (target - candidates[index] >= 0) 33 | dfs(target - candidates[index], [...combine, candidates[index]], index); 34 | } 35 | dfs(target, [], 0); 36 | 37 | return result; 38 | }; 39 | // @lc code=end 40 | -------------------------------------------------------------------------------- /回溯/40.组合总和-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=40 lang=javascript 3 | * 4 | * [40] 组合总和 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} candidates 10 | * @param {number} target 11 | * @return {number[][]} 12 | */ 13 | var combinationSum2 = function (candidates, target) { 14 | /** 15 | * @author xun 16 | * @method 回溯 17 | * @timeComplexity O(2n × n) 18 | * @spaceComplexity O(N) 19 | */ 20 | candidates.sort((a, b) => a - b); 21 | 22 | const result = []; 23 | 24 | function dfs(candidates, combine, target) { 25 | for (let i = 0; i < candidates.length; i++) { 26 | let currentPath = [...combine, candidates[i]]; 27 | let currentTarget = target - candidates[i]; 28 | 29 | // 相同的情况跳过 30 | if (i > 0 && candidates[i - 1] === candidates[i]) continue; 31 | 32 | if (currentTarget === 0) result.push(currentPath); 33 | if (currentTarget >= candidates[i]) 34 | dfs(candidates.slice(i + 1), currentPath, currentTarget); 35 | } 36 | } 37 | 38 | dfs(candidates, [], target); 39 | return result; 40 | }; 41 | // @lc code=end 42 | -------------------------------------------------------------------------------- /回溯/46.全排列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=46 lang=javascript 3 | * 4 | * [46] 全排列 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number[][]} 11 | */ 12 | 13 | var permute = function (nums) { 14 | /** 15 | * @author xun 16 | * @method 回溯 17 | * @timeComplexity O(N) 18 | * @spaceComplexity O(N) 19 | */ 20 | const result = []; 21 | function dfs(index, array) { 22 | if (array.length === nums.length) { 23 | result.push([...array]); 24 | return; 25 | } 26 | for (let j = 0; j < nums.length; j++) { 27 | if (array.indexOf(nums[j]) === -1) { 28 | dfs(index + 1, [...array, nums[j]]); 29 | } 30 | } 31 | } 32 | 33 | dfs(0, []); 34 | return result; 35 | }; 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /回溯/47.全排列-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=47 lang=javascript 3 | * 4 | * [47] 全排列 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number[][]} 11 | */ 12 | var permuteUnique = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 搜索回溯 16 | * @timeComplexity O(N*N!) 17 | * @spaceComplexity O(N) 18 | */ 19 | const result = []; 20 | const vis = new Array(nums.length).fill(false); 21 | 22 | function backtrack(index, perm) { 23 | if (index === nums.length) { 24 | result.push(perm.slice()); 25 | return; 26 | } 27 | for (let i = 0; i < nums.length; i++) { 28 | if (vis[i] || (i > 0 && nums[i] === nums[i - 1] && !vis[i - 1])) continue; 29 | perm.push(nums[i]); 30 | 31 | vis[i] = true; 32 | backtrack(index + 1, perm); 33 | vis[i] = false; 34 | 35 | perm.pop(); 36 | } 37 | } 38 | nums.sort((a, b) => a - b); 39 | backtrack(0, []); 40 | 41 | return result; 42 | }; 43 | // @lc code=end 44 | -------------------------------------------------------------------------------- /回溯/51.n-皇后.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=51 lang=javascript 3 | * 4 | * [51] N 皇后 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} n 10 | * @return {string[][]} 11 | */ 12 | var solveNQueens = function (n) { 13 | /** 14 | * @author xun 15 | * @method 回溯 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const result = []; 20 | const path = []; 21 | 22 | backtrack(0, path); 23 | return result; 24 | 25 | function backtrack(row, temp) { 26 | if (row === n) { 27 | result.push( 28 | temp.map((c) => { 29 | const arr = new Array(n).fill("."); 30 | arr[c] = "Q"; 31 | return arr.join(""); 32 | }) 33 | ); 34 | } 35 | 36 | for (let col = 0; col < n; col++) { 37 | const canNoSet = temp.some((c, r) => { 38 | return c === col || r - c === row - col || r + c === row + col; 39 | }); 40 | 41 | if (canNoSet) continue; 42 | 43 | backtrack(row + 1, [...temp, col]); 44 | } 45 | } 46 | }; 47 | // @lc code=end 48 | -------------------------------------------------------------------------------- /回溯/78.子集.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=78 lang=javascript 3 | * 4 | * [78] 子集 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number[][]} 11 | */ 12 | var subsets = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 回溯 16 | */ 17 | const result = []; 18 | 19 | function backtrack(start, current) { 20 | result.push([...current]); 21 | 22 | for (let i = start; i < nums.length; i++) { 23 | current.push(nums[i]); 24 | backtrack(i + 1, current); 25 | current.pop(); 26 | } 27 | } 28 | 29 | backtrack(0, []); 30 | return result; 31 | }; 32 | // @lc code=end 33 | -------------------------------------------------------------------------------- /字符串/14.最长公共前缀.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=14 lang=javascript 3 | * 4 | * [14] 最长公共前缀 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string[]} strs 10 | * @return {string} 11 | */ 12 | var longestCommonPrefix = function (strs) { 13 | /** 14 | * @author xun 15 | * @method 纵向扫描 16 | * @timeComplexity O(MN) 17 | * @spaceComplexity O(1) 18 | */ 19 | if (!strs.length) return ""; 20 | 21 | let ans = strs[0]; 22 | 23 | for (let i = 1; i < strs.length; i++) { 24 | let j = 0; 25 | while (j < ans.length && ans[j] === strs[i][j]) { 26 | j++; 27 | } 28 | ans = ans.substring(0, j); 29 | if (ans === "") return ans; 30 | } 31 | return ans; 32 | }; 33 | // @lc code=end 34 | -------------------------------------------------------------------------------- /字符串/409.最长回文串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=409 lang=javascript 3 | * 4 | * [409] 最长回文串 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {number} 11 | */ 12 | var longestPalindrome = function (s) { 13 | const map = {}; 14 | let res = 0 15 | 16 | for (let i = 0; i < s.length; i++){ 17 | map[s[i]]=(map[s[i]]||0)+1 18 | } 19 | 20 | for (const char in map) { 21 | if(map[char]%2===1)res++ 22 | } 23 | 24 | return s.length-Math.max(0,res-1) 25 | }; 26 | // @lc code=end 27 | -------------------------------------------------------------------------------- /字符串/459.重复的子字符串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=459 lang=javascript 3 | * 4 | * [459] 重复的子字符串 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {boolean} 11 | */ 12 | var repeatedSubstringPattern = function (s) { 13 | if (!s.length) return false; 14 | 15 | function getNext(s) { 16 | const next = []; 17 | 18 | let j = 0; 19 | 20 | next.push(j); 21 | 22 | for (let i = 1; i < s.length; i++) { 23 | while (j > 0 && s[i] !== s[j]) { 24 | j = next[j - 1]; 25 | } 26 | 27 | if (s[i] === s[j]) { 28 | j++; 29 | } 30 | 31 | next.push(j); 32 | } 33 | return next; 34 | } 35 | 36 | const next = getNext(s); 37 | 38 | if ( 39 | next[next.length - 1] !== 0 && 40 | s.length % (s.length - next[next.length - 1]) === 0 41 | ) { 42 | return true; 43 | } 44 | 45 | return false; 46 | }; 47 | // @lc code=end 48 | -------------------------------------------------------------------------------- /字符串/58.最后一个单词的长度.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=58 lang=javascript 3 | * 4 | * [58] 最后一个单词的长度 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {number} 11 | */ 12 | var lengthOfLastWord = function (s) { 13 | /** 14 | * @author xun 15 | * @method 反向遍历 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let end = s.length - 1; 20 | 21 | while (end >= 0 && s[end] === " ") end--; 22 | 23 | if (end < 0) return 0; 24 | 25 | let start = end; 26 | while (start >= 0 && s[start] !== " ") start--; 27 | 28 | return end - start; 29 | }; 30 | // @lc code=end 31 | -------------------------------------------------------------------------------- /字符串/67.二进制求和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=67 lang=javascript 3 | * 4 | * [67] 二进制求和 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} a 10 | * @param {string} b 11 | * @return {string} 12 | */ 13 | var addBinary = function (a, b) { 14 | /** 15 | * @author xun 16 | * @method 字符串 17 | * @timeComplexity O(N) 18 | * @spaceComplexity O(1) 19 | */ 20 | let max = Math.max(a.length, b.length); 21 | 22 | let flag = 0; 23 | let result = ""; 24 | let current = 0; 25 | let i = 0; 26 | 27 | while (i < max) { 28 | current = +(a[a.length - i - 1] || 0) + +(b[b.length - i - 1] || 0) + flag; 29 | flag = current / 2 >= 1 ? 1 : 0; 30 | result = (current % 2) + result; 31 | i++; 32 | } 33 | return flag ? 1 + result : result; 34 | }; 35 | // @lc code=end 36 | -------------------------------------------------------------------------------- /字符串/680.验证回文字符串-ⅱ.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=680 lang=javascript 3 | * 4 | * [680] 验证回文字符串 Ⅱ 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {boolean} 11 | */ 12 | var validPalindrome = function (s) { 13 | /** 14 | * @author xun 15 | * @method 字符串 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let left = 0; 20 | let right = s.length - 1; 21 | 22 | while (left < right) { 23 | if (s[left] !== s[right]) { 24 | return ( 25 | isPalindrome(s, left + 1, right) || isPalindrome(s, left, right - 1) 26 | ); 27 | } 28 | left++; 29 | right--; 30 | } 31 | 32 | return true; 33 | }; 34 | 35 | function isPalindrome(s, left, right) { 36 | while (left < right) { 37 | // 给你一次机会了,你不中用啊 38 | if (s[left] !== s[right]) return false; 39 | 40 | left++; 41 | right--; 42 | } 43 | return true; 44 | } 45 | // @lc code=end 46 | -------------------------------------------------------------------------------- /手写题/寄生式组合继承.js: -------------------------------------------------------------------------------- 1 | function inheritPrototype(sourceType, children) { 2 | const prototype = Object(sourceType.prototype) 3 | 4 | prototype.constructor = children 5 | children.prototype=prototype 6 | } 7 | 8 | function Teacher(nickname, age, height) { 9 | this.nickname = nickname; 10 | } 11 | 12 | function Student(nickname) { 13 | Teacher.call(this, nickname); 14 | this.hobby = ["唱", "跳", "rap"]; 15 | } 16 | 17 | inheritPrototype(Teacher, Student); 18 | 19 | Teacher.prototype.running = function () { 20 | console.log("老师会跑步"); 21 | }; 22 | 23 | Student.prototype.running = function () { 24 | console.log("学生也会跑步"); 25 | }; 26 | 27 | const student = new Student("moment"); 28 | 29 | student.running(); // 学生也会跑步 30 | console.log(student.hobby); // ['唱', '跳', 'rap'] 31 | console.log(student.nickname); // comment 32 | -------------------------------------------------------------------------------- /手写题/最大异步任务并发数.js: -------------------------------------------------------------------------------- 1 | class Scheduler { 2 | constructor(limit) { 3 | this.limit = limit; 4 | this.number = 0; 5 | this.queue = []; 6 | } 7 | addTask(timeout, str) { 8 | this.queue.push([timeout, str]); 9 | } 10 | start() { 11 | if (this.number < this.limit && this.queue.length) { 12 | const [timeout, str] = this.queue.shift(); 13 | this.number++; 14 | 15 | setTimeout(() => { 16 | console.log(str); 17 | this.number--; 18 | this.start(); 19 | }, timeout * 1000); 20 | this.start(); 21 | } 22 | } 23 | } 24 | 25 | const scheduler = new Scheduler(2); // 设置最大并发数为 2 26 | 27 | scheduler.addTask(1, "Task 1"); // 在 1 秒后输出 'Task 1' 28 | scheduler.addTask(2, "Task 2"); // 在 2 秒后输出 'Task 2' 29 | scheduler.addTask(3, "Task 3"); // 在 3 秒后输出 'Task 3' 30 | scheduler.addTask(1, "Task 4"); // 在 1 秒后输出 'Task 4' 31 | 32 | scheduler.start(); 33 | -------------------------------------------------------------------------------- /排序/169.多数元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=169 lang=javascript 3 | * 4 | * [169] 多数元素 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var majorityElement = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 16 | * @timeComplexity O(n log n) 17 | * @spaceComplexity O(log n) 18 | */ 19 | nums.sort((a, b) => a - b); 20 | 21 | const mid = nums[Math.floor(nums.length / 2)]; 22 | 23 | return mid; 24 | }; 25 | // @lc code=end 26 | -------------------------------------------------------------------------------- /排序/179.最大数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=179 lang=javascript 3 | * 4 | * [179] 最大数 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {string} 11 | */ 12 | var largestNumber = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 16 | * @timeComplexity O(n log n log m) 17 | * @spaceComplexity O(log n) 18 | */ 19 | nums.sort((x, y) => { 20 | let i = 10; 21 | let j = 10; 22 | 23 | while (i <= x) i *= 10; 24 | 25 | while (j <= y) j *= 10; 26 | 27 | return "" + (i * y + x) - ("" + (j * x + y)); 28 | }); 29 | 30 | if (nums[0] === 0) return "0"; 31 | 32 | return nums.join(""); 33 | }; 34 | // @lc code=end 35 | -------------------------------------------------------------------------------- /排序/56.合并区间.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=56 lang=javascript 3 | * 4 | * [56] 合并区间 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[][]} intervals 10 | * @return {number[][]} 11 | */ 12 | var merge = function (intervals) { 13 | /** 14 | * @author xun 15 | * @method 排序 16 | * @timeComplexity O(nlg n) 17 | * @spaceComplexity O(log n) 18 | */ 19 | if (!intervals.length) return []; 20 | 21 | const result = []; 22 | intervals.sort((a, b) => a[0] - b[0]); 23 | let candidate = intervals[0]; 24 | 25 | for (let i = 1; i < intervals.length; i++) { 26 | const current = intervals[i]; 27 | if (candidate[1] >= current[0]) { 28 | candidate[1] = Math.max(current[1], candidate[1]); // 左端不变,右端取最大 29 | } else { 30 | result.push(candidate); 31 | candidate = current; 32 | } 33 | } 34 | result.push(candidate); 35 | return result; 36 | }; 37 | // @lc code=end 38 | -------------------------------------------------------------------------------- /排序/57.插入区间.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=57 lang=javascript 3 | * 4 | * [57] 插入区间 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[][]} intervals 10 | * @param {number[]} newInterval 11 | * @return {number[][]} 12 | */ 13 | var insert = function (intervals, newInterval) { 14 | /** 15 | * @author xun 16 | * @method 排序 17 | * @timeComplexity O(N log N) 18 | * @spaceComplexity O(N) 19 | */ 20 | const result = []; 21 | intervals.push(newInterval); 22 | intervals.sort((a, b) => a[0] - b[0]); 23 | 24 | let current = [-1, -1]; 25 | for (let i = 0; i < intervals.length; i++) { 26 | if (intervals[i][0] > current[1]) { 27 | current = [...intervals[i]]; 28 | result.push(current); 29 | } else if (intervals[i][1] > current[1]) { 30 | current[1] = intervals[i][1]; 31 | } 32 | } 33 | 34 | return result; 35 | }; 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /排序/冒泡排序.js: -------------------------------------------------------------------------------- 1 | const sort = (array) => { 2 | let isSwap = false; 3 | for (let i = 0; i < array.length - 1; i++) { 4 | for (let j = 0; j < array.length - 1 - i; j++) { 5 | if (array[j] > array[j + 1]) { 6 | [array[j], array[j + 1]] = [array[j + 1], array[j]]; 7 | isSwap = true; 8 | } 9 | } 10 | // 如果一轮比较重没有发生过变换,则立即停止排序,因为此时剩余的数字一定已经有序了 11 | if (isSwap === false) break; 12 | } 13 | return array; 14 | }; 15 | -------------------------------------------------------------------------------- /排序/希尔排序.js: -------------------------------------------------------------------------------- 1 | const sort = (array) => { 2 | const length = array.length; 3 | 4 | if (length < 2) return array; 5 | 6 | let gap = Math.floor(length / 2); 7 | 8 | while (gap > 0) { 9 | for (let i = gap; i < length; i++) { 10 | let j = i; 11 | let current = array[i]; 12 | 13 | while (j >= 0 && current < array[j - gap]) { 14 | array[j] = array[j - gap]; 15 | j -= gap; 16 | } 17 | 18 | array[j] = current; 19 | } 20 | gap = Math.floor(gap / 2); 21 | } 22 | 23 | return array; 24 | }; 25 | 26 | const array = [5, 8, 7, 10, 6, 9, 15, 1, 3]; 27 | console.time("s"); 28 | console.log(...sort(array)); 29 | console.timeEnd("s"); 30 | -------------------------------------------------------------------------------- /排序/归并排序.js: -------------------------------------------------------------------------------- 1 | function mergeSort(arr) { 2 | const len = arr.length; 3 | if (len < 2) return arr; 4 | let mid = Math.floor(len / 2); 5 | let left = arr.slice(0, mid); 6 | let right = arr.slice(mid); 7 | 8 | function merge(left, right) { 9 | const result = []; 10 | 11 | while (left.length > 0 && right.length > 0) { 12 | if (left[0] <= right[0]) { 13 | result.push(left.shift()); 14 | } else { 15 | result.push(right.shift()); 16 | } 17 | } 18 | 19 | while (left.length) result.push(left.shift()); 20 | while (right.length) result.push(right.shift()); 21 | 22 | return result; 23 | } 24 | 25 | return merge(mergeSort(left), mergeSort(right)); 26 | } 27 | 28 | // 测试 29 | const arr = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]; 30 | console.time("归并排序耗时"); 31 | console.log("arr :", ...mergeSort(arr)); 32 | console.timeEnd("归并排序耗时"); 33 | // arr : [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50] 34 | // 归并排序耗时: 0.739990234375ms 35 | -------------------------------------------------------------------------------- /排序/插入排序.js: -------------------------------------------------------------------------------- 1 | const sort = (array) => { 2 | for (let i = 0; i < array.length; i++) { 3 | let j = i; 4 | while (j >= 1 && array[j] < array[j - 1]) { 5 | [array[j], array[j - 1]] = [array[j - 1], array[j]]; 6 | } 7 | } 8 | return array; 9 | }; 10 | -------------------------------------------------------------------------------- /排序/桶排序.js: -------------------------------------------------------------------------------- 1 | function bucketSort(arr) { 2 | let max = Math.max(...arr); 3 | let min = Math.min(...arr); 4 | let bucketNum = parseInt((max - min) / arr.length) + 1; 5 | 6 | let bucketArr = new Array(bucketNum); 7 | for (var i = 0; i < bucketNum; i++) { 8 | bucketArr[i] = new Array(); 9 | } 10 | 11 | for (var i of arr) { 12 | let num = parseInt((i - min) / arr.length); 13 | bucketArr[num].push(i); 14 | } 15 | for (var i of bucketArr) { 16 | i.sort(); 17 | } 18 | let k = 0; 19 | for (var i = 0; i < bucketArr.length; i++) { 20 | for (var j = 0; j < bucketArr[i].length; j++) { 21 | arr[k++] = bucketArr[i][j]; 22 | } 23 | } 24 | return arr; 25 | } 26 | 27 | const array = [1, 20, 31, 58, 46, 5, 6, 7, 21, 32, 44, 59]; 28 | console.time("s"); 29 | console.log(...bucketSort(array)); 30 | console.timeEnd("s"); 31 | -------------------------------------------------------------------------------- /排序/选择排序.js: -------------------------------------------------------------------------------- 1 | // 二元选择排序 2 | const sort = (array) => { 3 | for (let i = 0; i < array.length / 2; i++) { 4 | let maxIndex = i; 5 | let minIndex = i; 6 | 7 | for (let j = i + 1; j < array.length - i; j++) { 8 | // 获取到最小的值 9 | if (array[minIndex] > array[j]) minIndex = j; 10 | // 获取到最小的值 11 | if (array[maxIndex] < array[j]) maxIndex = j; 12 | } 13 | 14 | if (minIndex === maxIndex) break; 15 | [array[i], array[minIndex]] = [array[minIndex], array[i]]; 16 | 17 | if (maxIndex === i) maxIndex = minIndex; 18 | 19 | const lastIndex = array.length - 1 - i; 20 | [array[maxIndex], array[lastIndex]] = [array[lastIndex], array[maxIndex]]; 21 | } 22 | return array; 23 | }; 24 | 25 | // 选择排序 26 | const baseSort = (array) => { 27 | for (let i = 0; i < array.length; i++) { 28 | let minIndex = i; 29 | for (let j = i + 1; j < array.length; j++) { 30 | if (array[j] < array[minIndex]) minIndex = j; 31 | } 32 | [array[i], array[minIndex]] = [array[minIndex], array[i]]; 33 | } 34 | return array; 35 | }; 36 | 37 | const array = [1, 24, 5, 9, 6, 8, 7, 10, 15]; 38 | console.time("s"); 39 | console.log(...sort(array)); 40 | console.timeEnd("s"); 41 | -------------------------------------------------------------------------------- /数学/118.杨辉三角.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=118 lang=javascript 3 | * 4 | * [118] 杨辉三角 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} numRows 10 | * @return {number[][]} 11 | */ 12 | var generate = function (numRows) { 13 | /** 14 | * @author xun 15 | * @method 数学 16 | * @timeComplexity O(N*N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const result = []; 20 | for (let i = 0; i < numRows; i++) { 21 | const row = new Array(i + 1).fill(1); 22 | for (let j = 1; j < row.length - 1; j++) { 23 | row[j] = result[i - 1][j - 1] + result[i - 1][j]; 24 | } 25 | result.push(row); 26 | } 27 | return result; 28 | }; 29 | 30 | // @lc code=end 31 | -------------------------------------------------------------------------------- /数学/119.杨辉三角-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=119 lang=javascript 3 | * 4 | * [119] 杨辉三角 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} rowIndex 10 | * @return {number[]} 11 | */ 12 | var getRow = function (rowIndex) { 13 | /** 14 | * @author xun 15 | * @method 线性递推 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const row = new Array(rowIndex + 1).fill(0); 20 | row[0] = 1; 21 | for (let i = 1; i <= rowIndex; i++) { 22 | row[i] = (row[i - 1] * (rowIndex - i + 1)) / i; 23 | } 24 | return row; 25 | }; 26 | // @lc code=end 27 | -------------------------------------------------------------------------------- /数学/258.各位相加.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=258 lang=javascript 3 | * 4 | * [258] 各位相加 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} num 10 | * @return {number} 11 | */ 12 | var addDigits = function (num) { 13 | /** 14 | * @author xun 15 | * @method 模拟 16 | * @timeComplexity O(log num) 17 | * @spaceComplexity O(1) 18 | */ 19 | // while (num >= 10) { 20 | // let sum = 0; 21 | // while (num > 0) { 22 | // sum += num % 10; 23 | // num = Math.floor(num / 10); 24 | // } 25 | // num = sum; 26 | // } 27 | // return num; 28 | /** 29 | * @author xun 30 | * @method 数学 31 | * @timeComplexity O(1) 32 | * @spaceComplexity O(1) 33 | */ 34 | return ((num - 1) % 9) + 1; 35 | }; 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /数学/453.最小操作次数使数组元素相等.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=453 lang=javascript 3 | * 4 | * [453] 最小操作次数使数组元素相等 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var minMoves = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 数学 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const min = Math.min(...nums); 20 | 21 | let result = 0; 22 | for (const num of nums) { 23 | result += num - min; // 每个数减最小 24 | } 25 | return result; 26 | }; 27 | // @lc code=end 28 | -------------------------------------------------------------------------------- /数学/50.pow-x-n.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=50 lang=javascript 3 | * 4 | * [50] Pow(x, n) 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} x 10 | * @param {number} n 11 | * @return {number} 12 | */ 13 | var myPow = function (x, n) { 14 | /** 15 | * @author xun 16 | * @method 二进制 17 | */ 18 | if (n < 0) { 19 | x = 1 / x; 20 | n = -n; 21 | } 22 | 23 | let result = 1; 24 | while (n) { 25 | if (n & 1) result *= x; 26 | x *= x; 27 | n >>>= 1; 28 | } 29 | return result; 30 | }; 31 | // @lc code=end 32 | -------------------------------------------------------------------------------- /数学/7.整数反转.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=7 lang=javascript 3 | * 4 | * [7] 整数反转 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} x 10 | * @return {number} 11 | */ 12 | var reverse = function (x) { 13 | /** 14 | * @author xun 15 | * @method 数学 16 | * @timeComplexity O(log |s| ) 17 | * @spaceComplexity O(1) 18 | */ 19 | 20 | let result = 0; 21 | 22 | while (x !== 0) { 23 | const digit = x % 10; 24 | x = ~~(x / 10); 25 | result = result * 10 + digit; 26 | if (result < Math.pow(-2, 31) || result > Math.pow(2, 31) - 1) return 0; 27 | } 28 | return result; 29 | }; 30 | // @lc code=end 31 | -------------------------------------------------------------------------------- /数学/9.回文数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=9 lang=javascript 3 | * 4 | * [9] 回文数 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} x 10 | * @return {boolean} 11 | */ 12 | var isPalindrome = function (x) { 13 | /** 14 | * @author xun 15 | * @method 反转一半数字 16 | * @timeComplexity O(log N) 17 | * @spaceComplexity O(1) 18 | */ 19 | if (x < 0 || (x % 10 === 0 && x !== 0)) return false; 20 | 21 | let result = 0; 22 | 23 | while (x > result) { 24 | result = result * 10 + (x % 10); 25 | x = Math.floor(x / 10); 26 | } 27 | // 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。 28 | // 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123, 29 | return x === result || x === Math.floor(result / 10); 30 | }; 31 | // @lc code=end 32 | -------------------------------------------------------------------------------- /栈/1190.反转每对括号间的子串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1190 lang=javascript 3 | * 4 | * [1190] 反转每对括号间的子串 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {string} 11 | */ 12 | var reverseParentheses = function (s) { 13 | /** 14 | * @author xun 15 | * @method 16 | * @timeComplexity O(N * N) 17 | * @spaceComplexity O(N) 18 | */ 19 | const stack = []; 20 | let str = ""; 21 | 22 | for (const char of s) { 23 | if (char === "(") { 24 | stack.push(str); 25 | str = ""; 26 | } else if (char === ")") { 27 | str = str.split("").reverse().join(""); 28 | str = stack[stack.length - 1] + str; 29 | stack.pop(); 30 | } else { 31 | str += char; 32 | } 33 | } 34 | 35 | return str; 36 | }; 37 | // @lc code=end 38 | -------------------------------------------------------------------------------- /栈/1249.移除无效的括号.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1249 lang=javascript 3 | * 4 | * [1249] 移除无效的括号 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {string} 11 | */ 12 | var minRemoveToMakeValid = function (s) { 13 | const stack = []; 14 | const arr = s.split(""); 15 | 16 | for (let i = 0; i < arr.length; i++) { 17 | const item = s[i]; 18 | if (item === "(") { 19 | stack.push(i); 20 | } else if (item === ")") { 21 | if (stack.length > 0) { 22 | stack.pop(); 23 | } else { 24 | arr[i] = ""; 25 | } 26 | } 27 | } 28 | 29 | for (const item of stack) { 30 | arr[item] = ""; 31 | } 32 | 33 | return arr.join(""); 34 | }; 35 | 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /栈/151.颠倒字符串中的单词.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=151 lang=javascript 3 | * 4 | * [151] 颠倒字符串中的单词 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {string} 11 | */ 12 | var reverseWords = function (s) { 13 | /** 14 | * @author xun 15 | * @method 栈 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(N) 18 | */ 19 | const words = []; 20 | let start = s.length - 1; 21 | 22 | for (let i = s.length - 1; i >= 0; i--) { 23 | if (s[i] === " ") { 24 | if (i < start) { 25 | words.push(s.slice(i + 1, start + 1)); 26 | } 27 | start = i - 1; 28 | } else if (i === 0) { 29 | words.push(s.slice(i, start + 1)); 30 | } 31 | } 32 | 33 | return words.join(" "); 34 | }; 35 | // @lc code=end 36 | -------------------------------------------------------------------------------- /栈/1614.括号的最大嵌套深度.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1614 lang=javascript 3 | * 4 | * [1614] 括号的最大嵌套深度 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {number} 11 | */ 12 | var maxDepth = function (s) { 13 | /** 14 | * @author xun 15 | * @method 栈 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let ans = 0; 20 | let size = 0; 21 | 22 | for (let i = 0; i < s.length; i++) { 23 | const char = s[i]; 24 | 25 | if (char === "(") { 26 | size++; 27 | 28 | ans = Math.max(ans, size); 29 | } else if (char === ")") { 30 | size--; 31 | } 32 | } 33 | 34 | return ans; 35 | }; 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /栈/20.有效的括号.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=20 lang=javascript 3 | * 4 | * [20] 有效的括号 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {boolean} 11 | */ 12 | var isValid = function (s) { 13 | const stack = []; 14 | const map = { 15 | "(": ")", 16 | "{": "}", 17 | "[": "]", 18 | }; 19 | 20 | for (const item of s) { 21 | if (map[item]) { 22 | stack.push(item); 23 | } else { 24 | if (item !== map[stack.pop()]) return false; 25 | } 26 | } 27 | 28 | return !stack.length; 29 | }; 30 | 31 | // @lc code=end 32 | -------------------------------------------------------------------------------- /栈/224.基本计算器.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=224 lang=javascript 3 | * 4 | * [224] 基本计算器 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {number} 11 | */ 12 | var calculate = function (s) { 13 | /** 14 | * @author xun 15 | * @method 栈 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(N) 18 | */ 19 | let sign = 1; 20 | let result = 0; 21 | 22 | const valueStack = []; 23 | const signStack = []; 24 | 25 | for (let i = 0; i < s.length; i++) { 26 | if (s[i] === "+") sign = 1; 27 | else if (s[i] === "-") sign = -1; 28 | else if (s[i] === "(") { 29 | valueStack.push(result); 30 | signStack.push(sign); 31 | result = 0; 32 | sign = 1; 33 | } else if (s[i] === ")") 34 | result = result * signStack.pop() + valueStack.pop(); 35 | else if (Number(s[i])) { 36 | let n = s[i]; 37 | while (i + 1 && Number(s[i + 1])) n += s[i++ + 1]; 38 | result += sign * +n; 39 | } 40 | } 41 | 42 | return result; 43 | }; 44 | // @lc code=end 45 | -------------------------------------------------------------------------------- /栈/232.用栈实现队列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=232 lang=javascript 3 | * 4 | * [232] 用栈实现队列 5 | */ 6 | 7 | // @lc code=start 8 | 9 | var MyQueue = function () { 10 | this.stackIn = []; 11 | this.stackOut = []; 12 | }; 13 | 14 | /** 15 | * @param {number} x 16 | * @return {void} 17 | */ 18 | MyQueue.prototype.push = function (x) { 19 | this.stackIn.push(x); 20 | }; 21 | 22 | /** 23 | * @return {number} 24 | */ 25 | MyQueue.prototype.pop = function () { 26 | if (this.stackOut.length) { 27 | return this.stackOut.pop(); 28 | } 29 | 30 | while (this.stackIn.length) { 31 | this.stackOut.push(this.stackIn.pop()); 32 | } 33 | 34 | return this.stackOut.pop(); 35 | }; 36 | 37 | /** 38 | * @return {number} 39 | */ 40 | MyQueue.prototype.peek = function () { 41 | let x = this.pop(); 42 | this.stackOut.push(x); 43 | 44 | return x; 45 | }; 46 | 47 | /** 48 | * @return {boolean} 49 | */ 50 | MyQueue.prototype.empty = function () { 51 | return !this.stackIn.length && !this.stackOut.length; 52 | }; 53 | 54 | /** 55 | * Your MyQueue object will be instantiated and called as such: 56 | * var obj = new MyQueue() 57 | * obj.push(x) 58 | * var param_2 = obj.pop() 59 | * var param_3 = obj.peek() 60 | * var param_4 = obj.empty() 61 | */ 62 | // @lc code=end 63 | -------------------------------------------------------------------------------- /栈/316.去除重复字母.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=316 lang=javascript 3 | * 4 | * [316] 去除重复字母 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {string} 11 | */ 12 | var removeDuplicateLetters = function (s) { 13 | /** 14 | * @author xun 15 | * @method 栈 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(N) 18 | */ 19 | const stack = []; 20 | 21 | for (let i = 0; i < s.length; i++) { 22 | const char = s[i]; 23 | 24 | if (s.includes(char)) continue; 25 | 26 | while ( 27 | stack[stack.length - 1] > char && 28 | s.indexOf(stack[stack.length - 1], i) > char 29 | ) { 30 | stack.pop(); 31 | } 32 | stack.push(char); 33 | } 34 | 35 | return stack.join(""); 36 | }; 37 | // @lc code=end 38 | -------------------------------------------------------------------------------- /栈/32.最长有效括号.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=32 lang=javascript 3 | * 4 | * [32] 最长有效括号 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {number} 11 | */ 12 | var longestValidParentheses = function (s) { 13 | /** 14 | * @author xun 15 | * @method 栈 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(N) 18 | */ 19 | let ans = 0; 20 | const stack = [-1]; 21 | 22 | for (let i = 0; i < s.length; i++) { 23 | if (i === "(") { 24 | stack.push(i); 25 | } else { 26 | stack.pop(); 27 | 28 | if (stack.length === 0) stack.pop(); 29 | else ans = Math.max(ans, i - stack[stack.length - 1]); 30 | } 31 | } 32 | }; 33 | // @lc code=end 34 | -------------------------------------------------------------------------------- /栈/331.验证二叉树的前序序列化.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=331 lang=javascript 3 | * 4 | * [331] 验证二叉树的前序序列化 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} preorder 10 | * @return {boolean} 11 | */ 12 | var isValidSerialization = function (preorder) { 13 | /** 14 | * @author xun 15 | * @method 栈 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(N) 18 | */ 19 | const n = preorder.length; 20 | let index = 0; 21 | const stack = [1]; 22 | 23 | while (index < n) { 24 | if (!stack.length) return false; 25 | 26 | if (preorder[index] === ",") { 27 | index++; 28 | } else if (preorder[index] === "#") { 29 | stack[stack.length - 1]--; 30 | 31 | if (stack[stack.length - 1] === 0) stack.pop(); 32 | index++; 33 | } else { 34 | while (index < n && preorder[index] !== ",") { 35 | index++; 36 | } 37 | stack[stack.length - 1]--; 38 | 39 | if (stack[stack.length - 1] === 0) { 40 | stack.pop(); 41 | } 42 | } 43 | } 44 | 45 | return stack.length === 0; 46 | }; 47 | // @lc code=end 48 | -------------------------------------------------------------------------------- /栈/402.移掉-k-位数字.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=402 lang=javascript 3 | * 4 | * [402] 移掉 K 位数字 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} num 10 | * @param {number} k 11 | * @return {string} 12 | */ 13 | var removeKdigits = function (num, k) { 14 | /** 15 | * @author xun 16 | * @method 贪心 + 单调栈 17 | * @timeComplexity O(N) 18 | * @spaceComplexity O(N) 19 | */ 20 | const stack = []; 21 | 22 | for (const digit of num) { 23 | while (stack.length > 0 && stack[stack.length - 1] > digit && k) { 24 | stack.pop(); 25 | k -= 1; 26 | } 27 | stack.push(digit); 28 | } 29 | 30 | for (; k > 0; k--) { 31 | stack.pop(); 32 | } 33 | 34 | let ans = ""; 35 | let isLeadingZero = 0; 36 | 37 | for (const digit of stack) { 38 | if (isLeadingZero && digit === "0") { 39 | continue; 40 | } 41 | isLeadingZero = false; 42 | ans += digit; 43 | } 44 | 45 | return ans === "" ? "0" : ans; 46 | }; 47 | // @lc code=end 48 | -------------------------------------------------------------------------------- /栈/496.下一个更大元素-i.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=496 lang=javascript 3 | * 4 | * [496] 下一个更大元素 I 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums1 10 | * @param {number[]} nums2 11 | * @return {number[]} 12 | */ 13 | var nextGreaterElement = function (nums1, nums2) { 14 | /** 15 | * @author xun 16 | * @method 单调栈+哈希表 17 | * @timeComplexity O(N+M) 18 | * @spaceComplexity O(N) 19 | */ 20 | const map = new Map(); 21 | const stack = []; 22 | 23 | for (let i = nums2.length - 1; i >= 0; i--) { 24 | const num = nums2[i]; 25 | 26 | while (stack.length && num >= stack[stack.length - 1]) { 27 | stack.pop(); 28 | } 29 | 30 | map.set(num, stack.length ? stack[stack.length - 1] : -1); 31 | stack.push(num); 32 | } 33 | 34 | return new Array(nums1.length) 35 | .fill(0) 36 | .map((undefined, index) => map.get(nums1[index])); 37 | }; 38 | // @lc code=end 39 | -------------------------------------------------------------------------------- /栈/581.最短无序连续子数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=581 lang=javascript 3 | * 4 | * [581] 最短无序连续子数组 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var findUnsortedSubarray = function (nums) { 13 | const n = nums.length; 14 | let max = -Number.MAX_VALUE; 15 | let min = Number.MAX_VALUE; 16 | let right = -1; 17 | let left = -1; 18 | 19 | for (let i = 0; i < n; i++) { 20 | if (max > nums[i]) { 21 | right = i; 22 | } else { 23 | max = nums[i]; 24 | } 25 | 26 | if (min < nums[n - i - 1]) { 27 | left = n - i - 1; 28 | } else { 29 | min = nums[n - i - 1]; 30 | } 31 | } 32 | 33 | return right === -1 ? 0 : right - left + 1; 34 | }; 35 | // @lc code=end 36 | -------------------------------------------------------------------------------- /栈/678.有效的括号字符串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=678 lang=javascript 3 | * 4 | * [678] 有效的括号字符串 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @return {boolean} 11 | */ 12 | var checkValidString = function (s) { 13 | /** 14 | * @author xun 15 | * @method 贪心 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let max = 0; 20 | let min = 0; 21 | 22 | for (const char of s) { 23 | if (char === "(") { 24 | min++; 25 | max++; 26 | } else if (char === ")") { 27 | min = Math.max(min - 1, 0); 28 | 29 | if (--max < 0) return false; 30 | } else { 31 | min = Math.max(min - 1, 0); 32 | max++; 33 | } 34 | } 35 | }; 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /栈/71.简化路径.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=71 lang=javascript 3 | * 4 | * [71] 简化路径 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} path 10 | * @return {string} 11 | */ 12 | var simplifyPath = function (path) { 13 | /** 14 | * @author xun 15 | * @method 栈 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(N) 18 | */ 19 | const names = path.split("/"); 20 | const stack = []; 21 | 22 | for (const name of names) { 23 | if (name === "..") { 24 | if (stack.length) stack.pop(); 25 | } else if (name && name !== ".") { 26 | stack.push(name); 27 | } 28 | } 29 | 30 | return stack.join("/"); 31 | }; 32 | // @lc code=end 33 | -------------------------------------------------------------------------------- /栈/84.柱状图中最大的矩形.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=84 lang=javascript 3 | * 4 | * [84] 柱状图中最大的矩形 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} heights 10 | * @return {number} 11 | */ 12 | var largestRectangleArea = function (heights) { 13 | /** 14 | * @author xun 15 | * @method 单调栈 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(N) 18 | */ 19 | let result = 0; 20 | const stack = [-1]; 21 | 22 | for (let i = 0; i < heights.length; i++) { 23 | while (stack.length > 1 && heights[stack[stack.length - 1]] > heights[i]) { 24 | result = Math.max( 25 | result, 26 | heights[stack.pop()] * (i - stack[stack.length - 1] - 1) 27 | ); 28 | } 29 | stack.push(i); 30 | } 31 | 32 | while (stack.length > 1) { 33 | result = Math.max( 34 | result, 35 | heights[stack.pop()] * (heights.length - stack[stack.length - 1] - 1) 36 | ); 37 | } 38 | 39 | return result; 40 | }; 41 | // @lc code=end 42 | -------------------------------------------------------------------------------- /栈/916.单词子集.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=916 lang=javascript 3 | * 4 | * [916] 单词子集 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string[]} words1 10 | * @param {string[]} words2 11 | * @return {string[]} 12 | */ 13 | var wordSubsets = function (words1, words2) { 14 | /** 15 | * @author xun 16 | * @method 哈希 17 | * @timeComplexity O(N) 18 | * @spaceComplexity O(N) 19 | */ 20 | const b = new Array(26).fill(0); 21 | 22 | words2.forEach((w) => { 23 | const temp = new Array(26).fill(0); 24 | 25 | for (const char of w) { 26 | const index = char.charCodeAt() - 97; 27 | 28 | if (temp[index]++ === b[index]) b[index]++; 29 | } 30 | }); 31 | 32 | return words1.filter((w) => { 33 | const temp = b.slice(); 34 | for (const c of w) { 35 | const index = c.charCodeAt() - 97; 36 | 37 | if (temp[index] > 0) temp[index]--; 38 | } 39 | 40 | return temp.every((current) => current === 0); 41 | }); 42 | }; 43 | // @lc code=end 44 | -------------------------------------------------------------------------------- /树/100.相同的树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=100 lang=javascript 3 | * 4 | * [100] 相同的树 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} p 18 | * @param {TreeNode} q 19 | * @return {boolean} 20 | */ 21 | var isSameTree = function (p, q) { 22 | if (p === null && q === null) return true; 23 | 24 | // 深度优先 25 | return ( 26 | q !== null && 27 | p !== null && 28 | p.val === q.val && 29 | isSameTree(p.left, q.left) && 30 | isSameTree(p.right, q.right) 31 | ); 32 | }; 33 | // @lc code=end 34 | -------------------------------------------------------------------------------- /树/1008.前序遍历构造二叉搜索树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1008 lang=javascript 3 | * 4 | * [1008] 前序遍历构造二叉搜索树 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {number[]} preorder 18 | * @return {TreeNode} 19 | */ 20 | var bstFromPreorder = function (preorder) { 21 | /** 22 | * @author xun 23 | * @method 深度遍历 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | if (!preorder.length) return null; 28 | 29 | const value = preorder.shift(); 30 | 31 | let root = new TreeNode(value); 32 | 33 | root.left = bstFromPreorder(preorder.filter((item) => item < value)); 34 | root.right = bstFromPreorder(preorder.filter((item) => item > value)); 35 | 36 | return root; 37 | }; 38 | // @lc code=end 39 | -------------------------------------------------------------------------------- /树/101.对称二叉树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=101 lang=javascript 3 | * 4 | * [101] 对称二叉树 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {boolean} 19 | */ 20 | var isSymmetric = function (root) { 21 | /** 22 | * @author xun 23 | * @method 递归 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | function check(p, q) { 28 | if (!p || !q) return !p && !q; 29 | 30 | if (p.val !== q.val) return false; 31 | 32 | return check(p.left, q.right) && check(p.right, q.left); 33 | } 34 | 35 | return check(root.left, root.right); 36 | }; 37 | // @lc code=end 38 | -------------------------------------------------------------------------------- /树/102.二叉树的层序遍历.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=102 lang=javascript 3 | * 4 | * [102] 二叉树的层序遍历 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {number[][]} 19 | */ 20 | var levelOrder = function (root) { 21 | /** 22 | * @author xun 23 | * @method 广度优先 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | 28 | const result = []; 29 | const stack = [root]; 30 | 31 | if (!root) return result; 32 | 33 | while (stack.length) { 34 | let n = stack.length; 35 | const current = []; 36 | 37 | while (n > 0) { 38 | const node = stack.shift(); 39 | current.push(node.val); 40 | 41 | node.left && stack.push(node.left); 42 | node.right && stack.push(node.right); 43 | n--; 44 | } 45 | 46 | result.push(current); 47 | } 48 | 49 | return result; 50 | }; 51 | // @lc code=end 52 | -------------------------------------------------------------------------------- /树/105.从前序与中序遍历序列构造二叉树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=105 lang=javascript 3 | * 4 | * [105] 从前序与中序遍历序列构造二叉树 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {number[]} preorder 18 | * @param {number[]} inorder 19 | * @return {TreeNode} 20 | */ 21 | var buildTree = function (preorder, inorder) { 22 | /** 23 | * @author xun 24 | * @method 递归 25 | * @timeComplexity O(N) 26 | * @spaceComplexity O(1) 27 | */ 28 | if (preorder.length === 0 || inorder.length === 0) return null; //递归终止条件 29 | 30 | const root = new TreeNode(preorder[0]); //根节点 31 | 32 | let rootIndex = inorder.indexOf(preorder[0]); //根节点在中序遍历中的索引 33 | 34 | root.left = buildTree( 35 | preorder.slice(1, rootIndex + 1), 36 | inorder.slice(0, rootIndex) 37 | ); //左子树 38 | 39 | root.right = buildTree( 40 | preorder.slice(rootIndex + 1), 41 | inorder.slice(rootIndex + 1) 42 | ); //右子树 43 | 44 | return root; 45 | }; 46 | // @lc code=end 47 | -------------------------------------------------------------------------------- /树/107.二叉树的层序遍历-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=107 lang=javascript 3 | * 4 | * [107] 二叉树的层序遍历 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {number[][]} 19 | */ 20 | var levelOrderBottom = function (root) { 21 | /** 22 | * @author xun 23 | * @method 广度优先 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | if (!root) return []; 28 | 29 | const result = []; //结果 30 | const queue = [root]; //遍历中用的队列 31 | 32 | //当队列中还有值 33 | while (queue.length) { 34 | let length = queue.length; 35 | const currentLevel = []; 36 | 37 | while (length > 0) { 38 | const node = queue.shift(); 39 | currentLevel.push(node.val); 40 | 41 | node.left && queue.push(node.left); 42 | node.right && queue.push(node.right); 43 | 44 | length--; 45 | } 46 | 47 | result.unshift(currentLevel); 48 | } 49 | return result; 50 | }; 51 | // @lc code=end 52 | -------------------------------------------------------------------------------- /树/108.将有序数组转换为二叉搜索树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=108 lang=javascript 3 | * 4 | * [108] 将有序数组转换为二叉搜索树 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {number[]} nums 18 | * @return {TreeNode} 19 | */ 20 | var sortedArrayToBST = function (nums) { 21 | if (!nums.length) return null; 22 | 23 | // 数组中间的节点可以作为树的跟节点 24 | const mid = Math.floor(nums.length / 2); 25 | 26 | const root = new TreeNode(nums[mid]); 27 | 28 | root.left = sortedArrayToBST(nums.slice(0, mid)); 29 | root.right = sortedArrayToBST(nums.slice(mid + 1)); 30 | 31 | return root; 32 | }; 33 | // @lc code=end 34 | -------------------------------------------------------------------------------- /树/110.平衡二叉树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=110 lang=javascript 3 | * 4 | * [110] 平衡二叉树 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {boolean} 19 | */ 20 | var isBalanced = function (root) { 21 | const res = { 22 | isBalancedTree: true, 23 | }; 24 | dfs(root, res); 25 | return res.isBalancedTree; 26 | }; 27 | 28 | /** 29 | * 求树的深度 30 | */ 31 | var maxDepth = function (root) { 32 | if (root == null) return 0; 33 | return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1; 34 | }; 35 | 36 | /** 37 | * 深度遍历 38 | */ 39 | var dfs = function (root, res) { 40 | if (root == null) return; 41 | if (Math.abs(maxDepth(root.left) - maxDepth(root.right)) > 1) { 42 | return (res.isBalancedTree = false); 43 | } 44 | dfs(root.left, res); 45 | dfs(root.right, res); 46 | }; 47 | 48 | // @lc code=end 49 | -------------------------------------------------------------------------------- /树/1110.删点成林.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1110 lang=javascript 3 | * 4 | * [1110] 删点成林 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @param {number[]} to_delete 19 | * @return {TreeNode[]} 20 | */ 21 | var delNodes = function (root, to_delete) { 22 | /** 23 | * @author xun 24 | * @method 深度优先搜索 25 | * @timeComplexity O(N) 26 | * @spaceComplexity O(N) 27 | */ 28 | const toDeleteSet = new Set(to_delete); 29 | const roots = []; 30 | 31 | dfs(root, true, toDeleteSet, roots); 32 | 33 | return roots; 34 | 35 | function dfs(node, isRoot, toDeleteSet, roots) { 36 | if (!node) return null; 37 | 38 | const deleted = toDeleteSet.has(node.val); 39 | node.left = dfs(node.left, deleted, toDeleteSet, roots); 40 | node.right = dfs(node.right, deleted, toDeleteSet, roots); 41 | 42 | if (deleted) return null; 43 | else if (isRoot) roots.push(node); 44 | 45 | return node; 46 | } 47 | }; 48 | // @lc code=end 49 | -------------------------------------------------------------------------------- /树/116.填充每个节点的下一个右侧节点指针.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=116 lang=javascript 3 | * 4 | * [116] 填充每个节点的下一个右侧节点指针 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * // Definition for a Node. 10 | * function Node(val, left, right, next) { 11 | * this.val = val === undefined ? null : val; 12 | * this.left = left === undefined ? null : left; 13 | * this.right = right === undefined ? null : right; 14 | * this.next = next === undefined ? null : next; 15 | * }; 16 | */ 17 | 18 | /** 19 | * @param {Node} root 20 | * @return {Node} 21 | */ 22 | var connect = function (root) { 23 | /** 24 | * @author xun 25 | * @method 使用已建立的next指针 26 | * @timeComplexity O(N) 27 | * @spaceComplexity O(1) 28 | */ 29 | if (!root) return root; 30 | 31 | const queue = [root]; 32 | 33 | while (queue.length) { 34 | const n = queue.length; 35 | let i = 0; 36 | while (i < n) { 37 | const node = queue.shift(); 38 | 39 | if (i < n - 1) node.next = queue[0]; 40 | 41 | node.left && queue.push(node.left); 42 | node.right && queue.push(node.right); 43 | 44 | i++; 45 | } 46 | } 47 | return root; 48 | }; 49 | // @lc code=end 50 | -------------------------------------------------------------------------------- /树/124.二叉树中的最大路径和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=124 lang=javascript 3 | * 4 | * [124] 二叉树中的最大路径和 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {number} 19 | */ 20 | var maxPathSum = function (root) { 21 | /** 22 | * @author xun 23 | * @method 递归 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | let maxSum = Number.MIN_SAFE_INTEGER; 28 | 29 | function dfs(root) { 30 | if (root === null) return 0; 31 | 32 | const left = dfs(root.left); 33 | const right = dfs(root.right); 34 | 35 | // 当前子树内部的最大路径和 36 | const innerMaxSum = root.val + left + right; 37 | 38 | maxSum = Math.max(maxSum, innerMaxSum); 39 | 40 | // 当前子树对外提供的最大和 41 | const outputMaxSum = root.val + Math.max(0, left, right); 42 | 43 | // 如果对外提供的路径和为负,直接返回0,否则直接返回 44 | return outputMaxSum <= 0 ? 0 : outputMaxSum; 45 | } 46 | 47 | dfs(root); 48 | 49 | return maxSum; 50 | }; 51 | // @lc code=end 52 | -------------------------------------------------------------------------------- /树/145.二叉树的后序遍历.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=145 lang=javascript 3 | * 4 | * [145] 二叉树的后序遍历 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {number[]} 19 | */ 20 | var postorderTraversal = function (root) { 21 | /** 22 | * @author xun 23 | * @method 递归遍历 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | const result = []; 28 | const stack = [root]; 29 | if (!root) return result; 30 | 31 | while (stack.length) { 32 | const node = stack.pop(); 33 | 34 | result.unshift(node.val); 35 | node.left && stack.push(node.left); 36 | 37 | node.right && stack.push(node.right); 38 | } 39 | return result; 40 | }; 41 | // @lc code=end 42 | -------------------------------------------------------------------------------- /树/199.二叉树的右视图.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=199 lang=javascript 3 | * 4 | * [199] 二叉树的右视图 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {number[]} 19 | */ 20 | var rightSideView = function (root) { 21 | /** 22 | * @author xun 23 | * @method 广度优先 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | const result = []; 28 | const stack = [root]; 29 | 30 | if (!root) return result; 31 | 32 | while (stack.length) { 33 | let n = stack.length; 34 | 35 | while (n--) { 36 | const node = stack.shift(); 37 | 38 | if (n === 0) result.push(node.val); 39 | 40 | node.left && stack.push(node.left); 41 | node.right && stack.push(node.right); 42 | } 43 | } 44 | return result; 45 | }; 46 | // @lc code=end 47 | -------------------------------------------------------------------------------- /树/222.完全二叉树的节点个数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=222 lang=javascript 3 | * 4 | * [222] 完全二叉树的节点个数 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {number} 19 | */ 20 | var countNodes = function (root) { 21 | /** 22 | * @author xun 23 | * @method 递归 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | function traverse(node) { 28 | // 左节点+右节点+1 29 | if (node === null) return 0; 30 | 31 | let leftNum = traverse(node.left); 32 | let rightNum = traverse(node.right); 33 | 34 | return leftNum + rightNum + 1; 35 | } 36 | return traverse(root); 37 | }; 38 | // @lc code=end 39 | -------------------------------------------------------------------------------- /树/226.翻转二叉树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=226 lang=javascript 3 | * 4 | * [226] 翻转二叉树 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {TreeNode} 19 | */ 20 | var invertTree = function (root) { 21 | /** 22 | * @author xun 23 | * @method 递归 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | if (root === null) return null; 28 | 29 | const left = invertTree(root.left); 30 | const right = invertTree(root.right); 31 | 32 | root.left = right; 33 | root.right = left; 34 | 35 | return root; 36 | }; 37 | // @lc code=end 38 | -------------------------------------------------------------------------------- /树/230.二叉搜索树中第k小的元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=230 lang=javascript 3 | * 4 | * [230] 二叉搜索树中第K小的元素 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @param {number} k 19 | * @return {number} 20 | */ 21 | var kthSmallest = function (root, k) { 22 | /** 23 | * @author xun 24 | * @method 中序遍历 25 | * @timeComplexity O(H+k) 26 | * @spaceComplexity O(H) 27 | */ 28 | const stack = []; 29 | 30 | while (root !== null || stack.length) { 31 | while (root !== null) { 32 | stack.push(root); 33 | root = root.left; 34 | } 35 | root = stack.pop(); 36 | --k; 37 | if (k === 0) { 38 | break; 39 | } 40 | root = root.right; 41 | } 42 | return root.val; 43 | }; 44 | // @lc code=end 45 | -------------------------------------------------------------------------------- /树/236.二叉树的最近公共祖先.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=236 lang=javascript 3 | * 4 | * [236] 二叉树的最近公共祖先 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val) { 11 | * this.val = val; 12 | * this.left = this.right = null; 13 | * } 14 | */ 15 | /** 16 | * @param {TreeNode} root 17 | * @param {TreeNode} p 18 | * @param {TreeNode} q 19 | * @return {TreeNode} 20 | */ 21 | var lowestCommonAncestor = function (root, p, q) { 22 | /** 23 | * @author xun 24 | * @method 递归 25 | * @timeComplexity O(N) 26 | * @spaceComplexity O(N) 27 | */ 28 | if (root === null || p === root || q === root) return root; 29 | 30 | let left = lowestCommonAncestor(root.left, p, q); 31 | let right = lowestCommonAncestor(root.right, p, q); 32 | 33 | if (left && right) return root; 34 | 35 | return left ? left : right; 36 | }; 37 | // @lc code=end 38 | -------------------------------------------------------------------------------- /树/257.二叉树的所有路径.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=257 lang=javascript 3 | * 4 | * [257] 二叉树的所有路径 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {string[]} 19 | */ 20 | var binaryTreePaths = function (root) { 21 | /** 22 | * @author xun 23 | * @method 深度优先 24 | * @timeComplexity O(N*N) 25 | * @spaceComplexity O(N*N) 26 | */ 27 | const paths = []; 28 | 29 | function dfs(root, path) { 30 | if (root) { 31 | path += root.val.toString(); 32 | 33 | if (root.left === null && root.right === null) { 34 | // 当前节点是叶子节点 35 | paths.push(path); 36 | } else { 37 | path += "->"; 38 | dfs(root.left, path); 39 | dfs(root.right, path); 40 | } 41 | } 42 | } 43 | 44 | dfs(root, ""); 45 | return paths; 46 | }; 47 | // @lc code=end 48 | -------------------------------------------------------------------------------- /树/404.左叶子之和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=404 lang=javascript 3 | * 4 | * [404] 左叶子之和 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {number} 19 | */ 20 | var sumOfLeftLeaves = function (root) { 21 | /** 22 | * @author xun 23 | * @method 递归 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | if (!root) return 0; 28 | 29 | let result = 0; 30 | 31 | if (root.left && !root.left.left && !root.left.right) { 32 | result = root.left.val; 33 | } 34 | 35 | return result + sumOfLeftLeaves(root.left) + sumOfLeftLeaves(root.right); 36 | }; 37 | // @lc code=end 38 | -------------------------------------------------------------------------------- /树/429.n-叉树的层序遍历.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=429 lang=javascript 3 | * 4 | * [429] N 叉树的层序遍历 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * // Definition for a Node. 10 | * function Node(val,children) { 11 | * this.val = val; 12 | * this.children = children; 13 | * }; 14 | */ 15 | 16 | /** 17 | * @param {Node|null} root 18 | * @return {number[][]} 19 | */ 20 | var levelOrder = function (root) { 21 | /** 22 | * @author xun 23 | * @method 广度优先遍历 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | 28 | const result = []; 29 | const stack = [root]; 30 | 31 | if (!root) return result; 32 | 33 | while (stack.length) { 34 | const n = stack.length; 35 | const level = []; 36 | 37 | for (let i = 0; i < n; i++) { 38 | const node = stack.shift(); 39 | level.push(node.val); 40 | 41 | for (const child of node.children) { 42 | stack.push(child); 43 | } 44 | } 45 | result.push(level); 46 | } 47 | 48 | return result; 49 | }; 50 | // @lc code=end 51 | -------------------------------------------------------------------------------- /树/509.斐波那契数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=509 lang=javascript 3 | * 4 | * [509] 斐波那契数 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} n 10 | * @return {number} 11 | */ 12 | 13 | var fib = function (n) { 14 | /** 15 | * @author xun 16 | * @method 动态规划 17 | * @timeComplexity O(N) 18 | * @spaceComplexity O(1) 19 | */ 20 | // const dp = [0, 1]; 21 | 22 | // for (let i = 2; i <= n; i++) { 23 | // dp[i] = dp[i - 1] + dp[i - 2]; 24 | // } 25 | 26 | // return dp[n]; 27 | /** 28 | * @author xun 29 | * @method 通项公式 30 | */ 31 | const sqrt5 = Math.sqrt(5); 32 | 33 | const fibN = Math.pow((1 + sqrt5) / 2, n) - Math.pow((1 - sqrt5) / 2, n); 34 | 35 | return Math.round(fibN / sqrt5); 36 | }; 37 | // @lc code=end 38 | -------------------------------------------------------------------------------- /树/543.二叉树的直径.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=543 lang=javascript 3 | * 4 | * [543] 二叉树的直径 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {number} 19 | */ 20 | var diameterOfBinaryTree = function (root) { 21 | if (root === null || (root.left === null && root.right === null)) return 0; 22 | 23 | let result = 0; 24 | 25 | function dfs(root) { 26 | if (root === null) return 0; 27 | let left = dfs(root.left); 28 | let right = dfs(root.right); 29 | 30 | result = Math.max(result, left + right); 31 | 32 | return Math.max(left, right) + 1; 33 | } 34 | dfs(root); 35 | return result; 36 | }; 37 | // @lc code=end 38 | -------------------------------------------------------------------------------- /树/572.另一棵树的子树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=572 lang=javascript 3 | * 4 | * [572] 另一棵树的子树 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @param {TreeNode} subRoot 19 | * @return {boolean} 20 | */ 21 | var isSubtree = function (root, subRoot) { 22 | /** 23 | * @author xun 24 | * @method 深度优先遍历 25 | * @timeComplexity O(N) 26 | * @spaceComplexity O(N) 27 | */ 28 | function isSameTree(p, q) { 29 | if (!p && !q) return true; 30 | if ( 31 | p && 32 | q && 33 | q.val === p.val && 34 | isSameTree(p.left, q.left) && 35 | isSameTree(q.right, p.right) 36 | ) { 37 | return true; 38 | } 39 | return false; 40 | } 41 | if (root === null) return false; 42 | 43 | if (isSameTree(root, subRoot)) return true; 44 | 45 | return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot); 46 | }; 47 | // @lc code=end 48 | -------------------------------------------------------------------------------- /树/652.寻找重复的子树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=652 lang=javascript 3 | * 4 | * [652] 寻找重复的子树 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {TreeNode[]} 19 | */ 20 | var findDuplicateSubtrees = function (root) { 21 | /** 22 | * @author xun 23 | * @method 哈希表 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | const seen = new Map(); 28 | const repeat = new Set(); 29 | 30 | let index = 0; 31 | 32 | function dfs(node) { 33 | if (!node) return 0; 34 | 35 | const tri = [node.val, dfs(node.left), dfs(node.right)]; 36 | const hash = tri.toString(); 37 | 38 | if (seen.has(hash)) { 39 | const pair = seen.get(hash); 40 | repeat.add(pair[0]); 41 | 42 | return pair[1]; 43 | } else { 44 | seen.set(hash, [node, ++index]); 45 | return index; 46 | 47 | } 48 | } 49 | 50 | dfs(root); 51 | return [...repeat]; 52 | }; 53 | // @lc code=end 54 | -------------------------------------------------------------------------------- /树/654.最大二叉树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=654 lang=javascript 3 | * 4 | * [654] 最大二叉树 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {number[]} nums 18 | * @return {TreeNode} 19 | */ 20 | var constructMaximumBinaryTree = function (nums) { 21 | /** 22 | * @author xun 23 | * @method 单调栈 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | const length = nums.length; 28 | const stack = []; 29 | 30 | const tree = new Array(length).fill(0); 31 | 32 | for (let i = 0; i < length; i++) { 33 | tree[i] = new TreeNode(nums[i]); 34 | while (stack.length && nums[i] > nums[stack[stack.length - 1]]) { 35 | tree[i].left = tree[stack[stack.length - 1]]; 36 | stack.pop(); 37 | } 38 | 39 | if (stack.length) tree[stack[stack.length - 1]].right = tree[i]; 40 | 41 | stack.push(i); 42 | } 43 | 44 | return tree[stack[0]]; 45 | }; 46 | // @lc code=end 47 | -------------------------------------------------------------------------------- /树/687.最长同值路径.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=687 lang=javascript 3 | * 4 | * [687] 最长同值路径 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {number} 19 | */ 20 | var longestUnivaluePath = function (root) { 21 | /** 22 | * @author xun 23 | * @method 深度优先遍历 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | let res = 0; 28 | 29 | function dfs(root) { 30 | if (!root) return 0; 31 | 32 | let left = dfs(root.left); 33 | let right = dfs(root.right); 34 | let left1 = 0; 35 | let right1 = 0; 36 | 37 | if (root.left && root.left.val === root.val) left1 = left + 1; 38 | if (root.right && root.right.val === root.val) right1 = right + 1; 39 | 40 | res = Math.max(res, left1 + right1); 41 | return Math.max(left1, right1); 42 | } 43 | dfs(root); 44 | 45 | return res; 46 | }; 47 | // @lc code=end 48 | -------------------------------------------------------------------------------- /树/700.二叉搜索树中的搜索.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=700 lang=javascript 3 | * 4 | * [700] 二叉搜索树中的搜索 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @param {number} val 19 | * @return {TreeNode} 20 | */ 21 | var searchBST = function (root, val) { 22 | /** 23 | * @author xun 24 | * @method 迭代 25 | * @timeComplexity O(N) 26 | * @spaceComplexity O(1) 27 | */ 28 | while (root) { 29 | if (val === root.val) return root; 30 | 31 | root = val > root.val ? root.right : root.left; 32 | } 33 | 34 | return root; 35 | }; 36 | // @lc code=end 37 | -------------------------------------------------------------------------------- /树/701.二叉搜索树中的插入操作.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=701 lang=javascript 3 | * 4 | * [701] 二叉搜索树中的插入操作 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @param {number} val 19 | * @return {TreeNode} 20 | */ 21 | var insertIntoBST = function (root, val) { 22 | /** 23 | * @author xun 24 | * @method 模拟 25 | * @timeComplexity O(N) 26 | * @spaceComplexity O(1) 27 | */ 28 | if (root === null) return new TreeNode(val); 29 | 30 | let pos = root; 31 | 32 | while (pos !== null) { 33 | if (val < pos.val) { 34 | if (pos.left === null) { 35 | pos.left = new TreeNode(val); 36 | break; 37 | } else { 38 | pos = pos.left; 39 | } 40 | } else { 41 | if (pos.right === null) { 42 | pos.right = new TreeNode(val); 43 | break; 44 | } else { 45 | pos = pos.right; 46 | } 47 | } 48 | } 49 | 50 | return root; 51 | }; 52 | // @lc code=end 53 | -------------------------------------------------------------------------------- /树/94.二叉树的中序遍历.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=94 lang=javascript 3 | * 4 | * [94] 二叉树的中序遍历 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {number[]} 19 | */ 20 | var inorderTraversal = function (root) { 21 | /** 22 | * @author xun 23 | * @method 迭代 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | const res = []; 28 | const stack = []; 29 | 30 | while (root || stack.length) { 31 | while (root) { 32 | stack.push(root); 33 | root = root.left; 34 | } 35 | 36 | root = stack.pop(); 37 | res.push(root.val); 38 | root = root.right; 39 | } 40 | 41 | return res; 42 | }; 43 | // @lc code=end 44 | -------------------------------------------------------------------------------- /树/95.不同的二叉搜索树-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=95 lang=javascript 3 | * 4 | * [95] 不同的二叉搜索树 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {number} n 18 | * @return {TreeNode[]} 19 | */ 20 | var generateTrees = function (n) { 21 | /** 22 | * @author xun 23 | * @method 回溯 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | if (n === 0) return []; 28 | 29 | return generateSearchTrees(1, n); 30 | }; 31 | 32 | var generateSearchTrees = (start, end) => { 33 | if (start > end) { 34 | return [null]; 35 | } 36 | 37 | const result = []; 38 | for (let i = start; i <= end; i++) { 39 | let left = generateSearchTrees(start, i - 1); 40 | let right = generateSearchTrees(i + 1, end); 41 | 42 | for (let l = 0; l < left.length; l++) { 43 | for (let r = 0; r < right.length; r++) { 44 | let currentRoot = new TreeNode(i, left[l], right[r]); 45 | result.push(currentRoot); 46 | } 47 | } 48 | } 49 | return result; 50 | }; 51 | // @lc code=end 52 | -------------------------------------------------------------------------------- /树/96.不同的二叉搜索树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=96 lang=javascript 3 | * 4 | * [96] 不同的二叉搜索树 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} n 10 | * @return {number} 11 | */ 12 | var numTrees = function (n) { 13 | /** 14 | * @author xun 15 | * @method 动态规划 16 | * @timeComplexity O(N * N) 17 | * @spaceComplexity O(N) 18 | */ 19 | // const path = new Array(n + 1).fill(0); 20 | // path[0] = 1; 21 | // path[1] = 1; 22 | // for (let i = 2; i <= n; i++) { 23 | // for (let j = 1; j <= i; j++) { 24 | // path[i] += path[j - 1] * path[i - j]; 25 | // } 26 | // } 27 | // return path[n]; 28 | /** 29 | * @author xun 30 | * @method 数字 31 | * @timeComplexity O(N) 32 | * @spaceComplexity O(1) 33 | */ 34 | 35 | let result = 1; 36 | for (let i = 0; i < n; i++) { 37 | result = (result * 2 * (2 * i + 1)) / (i + 2); 38 | } 39 | return result; 40 | }; 41 | // @lc code=end 42 | -------------------------------------------------------------------------------- /树/979.在二叉树中分配硬币.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=979 lang=javascript 3 | * 4 | * [979] 在二叉树中分配硬币 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {number} 19 | */ 20 | var distributeCoins = function (root) { 21 | /** 22 | * @author xun 23 | * @method 深度优先遍历 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | let result = 0; 28 | 29 | function dfs(node) { 30 | if (!node) return 0; 31 | 32 | const left = dfs(node.left); 33 | const right = dfs(node.right); 34 | 35 | result += Math.abs(left) + Math.abs(right); 36 | return node.val + left + right - 1; 37 | } 38 | 39 | dfs(root); 40 | 41 | return result; 42 | }; 43 | // @lc code=end 44 | -------------------------------------------------------------------------------- /树/99.恢复二叉搜索树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=99 lang=javascript 3 | * 4 | * [99] 恢复二叉搜索树 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for a binary tree node. 10 | * function TreeNode(val, left, right) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.left = (left===undefined ? null : left) 13 | * this.right = (right===undefined ? null : right) 14 | * } 15 | */ 16 | /** 17 | * @param {TreeNode} root 18 | * @return {void} Do not return anything, modify root in-place instead. 19 | */ 20 | var recoverTree = function (root) { 21 | /** 22 | * @author xun 23 | * @method 隐式中序遍历 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(H) 26 | */ 27 | const stack = []; 28 | 29 | let x = null; 30 | let y = null; 31 | let pred = null; 32 | 33 | while (stack.length || root !== null) { 34 | while (root !== null) { 35 | stack.push(root); 36 | root = root.left; 37 | } 38 | root = stack.pop(); 39 | 40 | if (pred !== null && root.val < pred.val) { 41 | y = root; 42 | if (x === null) x = pred; 43 | else break; 44 | } 45 | pred = root; 46 | root = root.right; 47 | } 48 | [x.val, y.val] = [y.val, x.val]; 49 | }; 50 | 51 | // @lc code=end 52 | -------------------------------------------------------------------------------- /滑动窗口/219.存在重复元素-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=219 lang=javascript 3 | * 4 | * [219] 存在重复元素 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @param {number} k 11 | * @return {boolean} 12 | */ 13 | var containsNearbyDuplicate = function (nums, k) { 14 | /** 15 | * @author xun 16 | * @method 滑动窗口 17 | * @timeComplexity O(N) 18 | * @spaceComplexity O(K) 其中 k 是判断重复元素时允许的下标差的绝对值的最大值 19 | */ 20 | const set = new Set(); 21 | const length = nums.length; 22 | 23 | for (let i = 0; i < length; i++) { 24 | if (i > k) set.delete(nums[i - k - 1]); 25 | if (set.has(nums[i])) return true; 26 | 27 | set.add(nums[i]); 28 | } 29 | return false; 30 | }; 31 | // @lc code=end 32 | -------------------------------------------------------------------------------- /滑动窗口/904.水果成篮.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=904 lang=javascript 3 | * 4 | * [904] 水果成篮 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} fruits 10 | * @return {number} 11 | */ 12 | var totalFruit = function (fruits) { 13 | /** 14 | * @author xun 15 | * @method 滑动窗口 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | const length = fruits.length; 20 | const current = new Map(); 21 | 22 | let left = 0; 23 | let ans = 0; 24 | 25 | for (let right = 0; right < length; right++) { 26 | current.set(fruits[right], (current.get(fruits[right]) || 0) + 1); 27 | 28 | while (current.size > 2) { 29 | current.set(fruits[left], current.get(fruits[left]) - 1); 30 | 31 | if (current.get(fruits[left]) === 0) current.delete(fruits[left]); 32 | 33 | left++; 34 | } 35 | ans = Math.max(ans, right - left + 1); 36 | } 37 | 38 | return ans; 39 | }; 40 | // @lc code=end 41 | -------------------------------------------------------------------------------- /贪心/392.判断子序列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=392 lang=javascript 3 | * 4 | * [392] 判断子序列 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {string} s 10 | * @param {string} t 11 | * @return {boolean} 12 | */ 13 | var isSubsequence = function (s, t) { 14 | /** 15 | * @author xun 16 | * @method 贪心 17 | * @timeComplexity O(N) 18 | * @spaceComplexity O(1) 19 | */ 20 | let i = 0; 21 | for (let j = 0; j < t.length; j++) { 22 | if (s[i] === t[j]) i++; 23 | } 24 | 25 | return i === s.length; 26 | }; 27 | // @lc code=end 28 | -------------------------------------------------------------------------------- /贪心/435.无重叠区间.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=435 lang=javascript 3 | * 4 | * [435] 无重叠区间 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[][]} intervals 10 | * @return {number} 11 | */ 12 | var eraseOverlapIntervals = function (intervals) { 13 | /** 14 | * @author xun 15 | * @method 贪心算法 16 | * @timeComplexity O(N log N) 17 | * @spaceComplexity O(log n) 18 | */ 19 | 20 | const length = intervals.length; 21 | if (!length) return 0; 22 | 23 | intervals.sort((a, b) => a[1] - b[1]); 24 | 25 | let right = intervals[0][1]; 26 | let ans = 1; 27 | 28 | for (let i = 1; i < length; i++) { 29 | if (intervals[i][0] >= right) { 30 | ++ans; 31 | right = intervals[i][1]; 32 | } 33 | } 34 | 35 | return length - ans; 36 | }; 37 | // @lc code=end 38 | -------------------------------------------------------------------------------- /贪心/452.用最少数量的箭引爆气球.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=452 lang=javascript 3 | * 4 | * [452] 用最少数量的箭引爆气球 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[][]} points 10 | * @return {number} 11 | */ 12 | var findMinArrowShots = function (points) { 13 | /** 14 | * @author xun 15 | * @method 排序+贪心 16 | * @timeComplexity O(N LOG N) 17 | * @spaceComplexity O(LOG N) 18 | */ 19 | if (!points.length) return 0; 20 | 21 | points.sort((a, b) => a[1] - b[1]); 22 | 23 | let pos = points[0][1]; 24 | let result = 1; 25 | 26 | for (const balloon of points) { 27 | if (balloon[0] > pos) { 28 | pos = balloon[1]; 29 | result++; 30 | } 31 | } 32 | 33 | return result; 34 | }; 35 | // @lc code=end 36 | -------------------------------------------------------------------------------- /贪心/621.任务调度器.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=621 lang=javascript 3 | * 4 | * [621] 任务调度器 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {character[]} tasks 10 | * @param {number} n 11 | * @return {number} 12 | */ 13 | var leastInterval = function (tasks, n) { 14 | /** 15 | * @author xun 16 | * @method 贪心 17 | * @timeComplexity O(N) 18 | * @spaceComplexity O(N) 19 | */ 20 | const arr = new Array(26).fill(0); 21 | 22 | for (const c of tasks) { 23 | //找到最大次数 24 | arr[c.charCodeAt() - "A".charCodeAt()]++; 25 | } 26 | 27 | let max = 0; 28 | for (let i = 0; i < 26; i++) { 29 | max = Math.max(max, arr[i]); 30 | } 31 | 32 | // 计算前n-1行n的间隔的时间大小 33 | let result = (max - 1) * (n + 1); 34 | 35 | for (let i = 0; i < 26; i++) { 36 | //计算和最大次数相同的字母个数,然后累加进 result 37 | if (arr[i] === max) result++; 38 | } 39 | 40 | return Math.max(result, tasks.length); // 在tasks的长度和ret中取较大的一个 41 | }; 42 | // @lc code=end 43 | -------------------------------------------------------------------------------- /贪心/670.最大交换.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=670 lang=javascript 3 | * 4 | * [670] 最大交换 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} num 10 | * @return {number} 11 | */ 12 | var maximumSwap = function (num) { 13 | /** 14 | * @author xun 15 | * @method 贪心 16 | * @timeComplexity O(log num) 17 | * @spaceComplexity O(log num) 18 | */ 19 | const nums = [...("" + num)]; 20 | const n = nums.length; 21 | let maxIndex = n - 1; 22 | let index1 = -1; 23 | let index2 = -1; 24 | 25 | for (let i = maxIndex; i >= 0; i--) { 26 | if (nums[i] > nums[maxIndex]) { 27 | maxIndex = i; 28 | } else if (nums[i] < nums[maxIndex]) { 29 | index1 = i; 30 | index2 = maxIndex; 31 | } 32 | } 33 | 34 | if (index1 >= 0) { 35 | [nums[index1], nums[index2]] = [nums[index2], nums[index1]]; 36 | return Number(nums.join("")); 37 | } else { 38 | return num; 39 | } 40 | }; 41 | // @lc code=end 42 | -------------------------------------------------------------------------------- /贪心/674.最长连续递增序列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=674 lang=javascript 3 | * 4 | * [674] 最长连续递增序列 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number} 11 | */ 12 | var findLengthOfLCIS = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 贪心算法 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let ans = 0; 20 | const length = nums.length; 21 | let start = 0; 22 | for (let i = 0; i < length; i++) { 23 | if (i > 0 && nums[i] <= nums[i - 1]) start = i; 24 | 25 | ans = Math.max(ans, i - start + 1); 26 | } 27 | return ans; 28 | }; 29 | // @lc code=end 30 | -------------------------------------------------------------------------------- /贪心/769.最多能完成排序的块.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=769 lang=javascript 3 | * 4 | * [769] 最多能完成排序的块 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} arr 10 | * @return {number} 11 | */ 12 | var maxChunksToSorted = function (arr) { 13 | /** 14 | * @author xun 15 | * @method 贪心 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let m = 0; 20 | let res = 0; 21 | 22 | for (let i = 0; i < arr.length; i++) { 23 | m = Math.max(m, arr[i]); 24 | 25 | if (m === i) res++; 26 | } 27 | return res; 28 | }; 29 | // @lc code=end 30 | -------------------------------------------------------------------------------- /贪心/860.柠檬水找零.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=860 lang=javascript 3 | * 4 | * [860] 柠檬水找零 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} bills 10 | * @return {boolean} 11 | */ 12 | var lemonadeChange = function (bills) { 13 | /** 14 | * @author xun 15 | * @method 贪心算法 16 | * @timeComplexity O(N) 17 | * @spaceComplexity O(1) 18 | */ 19 | let five = 0; 20 | let ten = 0; 21 | 22 | for (const bill of bills) { 23 | if (bill === 5) { 24 | five += 1; 25 | } else if (bill === 10) { 26 | if (five === 0) return false; 27 | 28 | five -= 1; 29 | ten += 1; 30 | } else { 31 | if (five > 0 && ten > 0) { 32 | five -= 1; 33 | ten -= 1; 34 | } else if (five >= 3) five -= 3; 35 | else return false; 36 | } 37 | } 38 | return true; 39 | }; 40 | // @lc code=end 41 | -------------------------------------------------------------------------------- /递归和迭代/200.岛屿数量.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=200 lang=javascript 3 | * 4 | * [200] 岛屿数量 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {character[][]} grid 10 | * @return {number} 11 | */ 12 | var numIslands = function (grid) { 13 | /** 14 | * @author xun 15 | * @method 深度优先遍历 16 | * @timeComplexity O(MN) 17 | * @spaceComplexity O(MN) 18 | */ 19 | let count = 0; 20 | for (let i = 0; i < grid.length; i++) { 21 | for (let j = 0; j < grid[0].length; j++) { 22 | if (grid[i][j] === "1") { 23 | turnZero(i, j, grid); 24 | count++; 25 | } 26 | } 27 | } 28 | return count; 29 | 30 | function turnZero(i, j, grid) { 31 | if ( 32 | i < 0 || 33 | i >= grid.length || 34 | j < 0 || 35 | j >= grid[0].length || 36 | grid[i][j] !== "1" 37 | ) { 38 | return; 39 | } 40 | 41 | grid[i][j] = "2"; 42 | 43 | turnZero(i + 1, j, grid); 44 | turnZero(i - 1, j, grid); 45 | turnZero(i, j + 1, grid); 46 | turnZero(i, j - 1, grid); 47 | } 48 | }; 49 | // @lc code=end 50 | -------------------------------------------------------------------------------- /递归和迭代/695.岛屿的最大面积.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=695 lang=javascript 3 | * 4 | * [695] 岛屿的最大面积 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[][]} grid 10 | * @return {number} 11 | */ 12 | var maxAreaOfIsland = function (grid) { 13 | /** 14 | * @author xun 15 | * @method 深度优先 16 | * @timeComplexity O(MN) 17 | * @spaceComplexity O(MN) 18 | */ 19 | const row = grid.length; 20 | const col = grid[0].length; 21 | 22 | function dfs(x, y) { 23 | // 判断越界 24 | if (x < 0 || x >= row || y < 0 || y >= col || grid[x][y] === 0) return 0; 25 | 26 | grid[x][y] = 0; 27 | 28 | let ans = 1; 29 | const dx = [-1, 1, 0, 0]; 30 | const dy = [0, 0, 1, -1]; 31 | 32 | for (let i = 0; i < dx.length; i++) { 33 | ans += dfs(x + dx[i], y + dy[i]); 34 | } 35 | return ans; 36 | } 37 | 38 | let res = 0; 39 | for (let i = 0; i < row; i++) { 40 | for (let j = 0; j < col; j++) { 41 | res = Math.max(res, dfs(i, j)); 42 | } 43 | } 44 | 45 | return res; 46 | }; 47 | // @lc code=end 48 | -------------------------------------------------------------------------------- /递归和迭代/90.子集-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=90 lang=javascript 3 | * 4 | * [90] 子集 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number[]} nums 10 | * @return {number[][]} 11 | */ 12 | var subsetsWithDup = function (nums) { 13 | /** 14 | * @author xun 15 | * @method 递归 16 | * @timeComplexity O(n× 2**n) 17 | * @spaceComplexity O(n× 2**n) 18 | */ 19 | nums.sort((a, b) => a - b); 20 | 21 | let temp = []; 22 | const ans = []; 23 | 24 | function dfs(choosePre, current, nums) { 25 | if (current === nums.length) { 26 | ans.push(temp.slice()); 27 | return; 28 | } 29 | 30 | dfs(false, current + 1, nums); 31 | if (!choosePre && current > 0 && nums[current - 1] === nums[current]) { 32 | return; 33 | } 34 | 35 | temp.push(nums[current]); 36 | 37 | dfs(true, current + 1, nums); 38 | 39 | temp = temp.slice(0, temp.length - 1); 40 | } 41 | dfs(false, 0, nums); 42 | 43 | return ans; 44 | }; 45 | // @lc code=end 46 | -------------------------------------------------------------------------------- /链表/1019.链表中的下一个更大节点.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1019 lang=javascript 3 | * 4 | * [1019] 链表中的下一个更大节点 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @return {number[]} 18 | */ 19 | var nextLargerNodes = function (head) { 20 | /** 21 | * @author xun 22 | * @method 单调栈 23 | * @timeComplexity O(N) 24 | * @spaceComplexity O(N) 25 | */ 26 | const ans = []; 27 | const stack = []; 28 | 29 | let current = head; 30 | let index = 0; 31 | 32 | while (current) { 33 | ans.push(0); 34 | 35 | while (stack.length && stack[stack.length - 1][0] < current.val) { 36 | ans[stack.pop()[1]] = current.val; 37 | } 38 | 39 | stack.push([current.val, index]); 40 | current = current.next; 41 | 42 | index++; 43 | } 44 | 45 | return ans; 46 | }; 47 | // @lc code=end 48 | -------------------------------------------------------------------------------- /链表/117.填充每个节点的下一个右侧节点指针-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=117 lang=javascript 3 | * 4 | * [117] 填充每个节点的下一个右侧节点指针 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * // Definition for a Node. 10 | * function Node(val, left, right, next) { 11 | * this.val = val === undefined ? null : val; 12 | * this.left = left === undefined ? null : left; 13 | * this.right = right === undefined ? null : right; 14 | * this.next = next === undefined ? null : next; 15 | * }; 16 | */ 17 | 18 | /** 19 | * @param {Node} root 20 | * @return {Node} 21 | */ 22 | var connect = function (root) { 23 | if (!root) return root; 24 | 25 | let queue = [root]; 26 | let nextQueue = []; 27 | 28 | while (queue.length > 0) { 29 | const node = queue.shift(); 30 | 31 | node.left && nextQueue.push(node.left); 32 | node.right && nextQueue.push(node.right); 33 | 34 | if (queue.length > 0) node.next = queue[0]; 35 | else { 36 | node.next = null; 37 | queue = nextQueue; 38 | nextQueue = []; 39 | } 40 | } 41 | return root; 42 | }; 43 | 44 | // @lc code=end 45 | -------------------------------------------------------------------------------- /链表/1290.二进制链表转整数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1290 lang=javascript 3 | * 4 | * [1290] 二进制链表转整数 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @return {number} 18 | */ 19 | var getDecimalValue = function (head) { 20 | /** 21 | * @author xun 22 | * @method 模拟 23 | * @timeComplexity O(N) 24 | * @spaceComplexity O(1) 25 | */ 26 | let node = head; 27 | let ans = 0; 28 | 29 | while (node !== null) { 30 | ans = ans * 2 + node.val; 31 | node = node.next; 32 | } 33 | return ans; 34 | }; 35 | // @lc code=end 36 | -------------------------------------------------------------------------------- /链表/141.环形链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=141 lang=javascript 3 | * 4 | * [141] 环形链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val) { 11 | * this.val = val; 12 | * this.next = null; 13 | * } 14 | */ 15 | 16 | /** 17 | * @param {ListNode} head 18 | * @return {boolean} 19 | */ 20 | var hasCycle = function (head) { 21 | /** 22 | * @author xun 23 | * @method 哈希表 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | // const cache = new Set(); 28 | 29 | // while (head) { 30 | // if (cache.has(head)) { 31 | // // 条件满足,返回 true 32 | // return true; 33 | // } else { 34 | // cache.add(head); 35 | // } 36 | // head = head.next; 37 | // } 38 | // // 遍历完还不满足返回 false 39 | // return false; 40 | 41 | /** 42 | * @author xun 43 | * @method 快慢指针 44 | * @timeComplexity O(N) 45 | * @spaceComplexity O(1) 46 | */ 47 | let fast = head; 48 | let slow = head; 49 | while (fast && fast.next) { 50 | fast = fast.next.next; 51 | slow = slow.next; 52 | if (slow === fast) return true; 53 | } 54 | return false; 55 | }; 56 | // @lc code=end 57 | -------------------------------------------------------------------------------- /链表/143.重排链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=143 lang=javascript 3 | * 4 | * [143] 重排链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @return {void} Do not return anything, modify head in-place instead. 18 | */ 19 | var reorderList = function (head) { 20 | /** 21 | * @author xun 22 | * @method 双向队列 23 | * @timeComplexity O(N) 24 | * @spaceComplexity O(N) 25 | */ 26 | if (head === null) return head; 27 | const queue = []; 28 | let p = head; 29 | 30 | // 链表入队 31 | while (p) { 32 | queue.push(p); 33 | p = p.next; 34 | } 35 | 36 | while (queue.length > 2) { 37 | // 队头 38 | const head = queue.shift(); 39 | // 队尾 40 | let tail = queue.pop(); 41 | tail.next = head.next; 42 | head.next = tail; 43 | } 44 | queue[queue.length - 1].next = null; 45 | 46 | return head; 47 | }; 48 | // @lc code=end 49 | -------------------------------------------------------------------------------- /链表/146.lru-缓存.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=146 lang=javascript 3 | * 4 | * [146] LRU 缓存 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * @param {number} capacity 10 | */ 11 | class LRUCache { 12 | constructor(capacity) { 13 | this.max = capacity; 14 | this.cache = new Map(); 15 | } 16 | 17 | get(key) { 18 | if (this.cache.has(key)) { 19 | const temp = this.cache.get(key); 20 | 21 | this.cache.delete(key); 22 | this.cache.set(key, temp); 23 | return temp; 24 | } 25 | return -1; 26 | } 27 | put(key, value) { 28 | if (this.cache.has(key)) { 29 | this.cache.delete(key); 30 | } else if (this.cache.size >= this.max) { 31 | this.cache.delete(this.cache.keys().next().value); 32 | } 33 | this.cache.set(key, value); 34 | } 35 | } 36 | 37 | /** 38 | * Your LRUCache object will be instantiated and called as such: 39 | * var obj = new LRUCache(capacity) 40 | * var param_1 = obj.get(key) 41 | * obj.put(key,value) 42 | */ 43 | // @lc code=end 44 | -------------------------------------------------------------------------------- /链表/147.对链表进行插入排序.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=147 lang=javascript 3 | * 4 | * [147] 对链表进行插入排序 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @return {ListNode} 18 | */ 19 | var insertionSortList = function (head) { 20 | /** 21 | * @author xun 22 | * @method 23 | * @timeComplexity O(N * N) 24 | * @spaceComplexity O(1) 25 | */ 26 | 27 | if (!head) return head; 28 | 29 | let current = head; 30 | const result = new ListNode(0); 31 | 32 | while (current !== null) { 33 | let temp = result; 34 | 35 | while (temp.next !== null && temp.next.val < current.val) { 36 | temp = temp.next; 37 | } 38 | 39 | const node = temp.next; 40 | temp.next = current; 41 | current = current.next; 42 | 43 | temp.next.next = node; 44 | } 45 | 46 | return result.next; 47 | }; 48 | // @lc code=end 49 | -------------------------------------------------------------------------------- /链表/1669.合并两个链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1669 lang=javascript 3 | * 4 | * [1669] 合并两个链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} list1 17 | * @param {number} a 18 | * @param {number} b 19 | * @param {ListNode} list2 20 | * @return {ListNode} 21 | */ 22 | var mergeInBetween = function (list1, a, b, list2) { 23 | /** 24 | * @author xun 25 | * @method 模拟 26 | * @timeComplexity O(N + M) 27 | * @spaceComplexity O(1) 28 | */ 29 | let planA = list1; 30 | for (let i = 0; i < a - 1; i++) { 31 | planA = planA.next; 32 | } 33 | 34 | let planB = planA; 35 | 36 | for (let i = 0; i < b - a + 2; i++) { 37 | planB = planB.next; 38 | } 39 | 40 | planA.next = list2; 41 | 42 | while (list2.next) { 43 | list2 = list2.next; 44 | } 45 | 46 | list2.next = planB; 47 | 48 | return list1; 49 | }; 50 | // @lc code=end 51 | -------------------------------------------------------------------------------- /链表/1721.交换链表中的节点.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=1721 lang=javascript 3 | * 4 | * [1721] 交换链表中的节点 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @param {number} k 18 | * @return {ListNode} 19 | */ 20 | var swapNodes = function (head, k) { 21 | /** 22 | * @author xun 23 | * @method 快慢指针 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(1) 26 | */ 27 | let current = head; 28 | for (let i = 0; i < k - 1; i++) { 29 | current = current.next; 30 | } 31 | 32 | let currentFirst = current; 33 | let currentSecond = head; 34 | 35 | while (current.next) { 36 | current = current.next; 37 | currentSecond = currentSecond.next; 38 | } 39 | 40 | [currentFirst.val, currentSecond.val] = [currentSecond.val, currentFirst.val]; 41 | 42 | return head; 43 | }; 44 | // @lc code=end 45 | -------------------------------------------------------------------------------- /链表/19.删除链表的倒数第-n-个结点.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=19 lang=javascript 3 | * 4 | * [19] 删除链表的倒数第 N 个结点 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @param {number} n 18 | * @return {ListNode} 19 | */ 20 | var removeNthFromEnd = function (head, n) { 21 | /** 22 | * @author xun 23 | * @method 快慢指针 24 | * @时间复杂度 O(L) 25 | * @空间复杂度 O(1) 26 | */ 27 | let slow = head; 28 | let fast = head; 29 | 30 | let i = 0; 31 | while (i < n) { 32 | fast = fast.next; 33 | i++; 34 | } 35 | 36 | if (fast === null) return head.next; 37 | 38 | while (fast.next !== null) { 39 | fast = fast.next; 40 | slow = slow.next; 41 | } 42 | 43 | slow.next = slow.next.next; 44 | 45 | return head; 46 | }; 47 | // @lc code=end 48 | -------------------------------------------------------------------------------- /链表/203.移除链表元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=203 lang=javascript 3 | * 4 | * [203] 移除链表元素 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @param {number} val 18 | * @return {ListNode} 19 | */ 20 | var removeElements = function (head, val) { 21 | /** 22 | * @author xun 23 | * @method 递归 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(N) 26 | */ 27 | // if (head === null) return head; 28 | // head.next = removeElements(head.next, val); 29 | // return head.val === val ? head.next : head; 30 | /** 31 | * @author xun 32 | * @method 迭代 33 | * @timeComplexity O(N) 34 | * @spaceComplexity O(1) 35 | */ 36 | 37 | const dummy = new ListNode(0); 38 | 39 | dummy.next = head; 40 | 41 | let temp = dummy; 42 | 43 | while (temp.next !== null) { 44 | if (temp.next.val === val) { 45 | temp.next = temp.next.next; 46 | } else { 47 | temp = temp.next; 48 | } 49 | } 50 | return dummy.next; 51 | }; 52 | // @lc code=end 53 | -------------------------------------------------------------------------------- /链表/2095.删除链表的中间节点.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=2095 lang=javascript 3 | * 4 | * [2095] 删除链表的中间节点 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @return {ListNode} 18 | */ 19 | var deleteMiddle = function (head) { 20 | /** 21 | * @author xun 22 | * @method 快慢指针 23 | * @timeComplexity O(N) 24 | * @spaceComplexity O(1) 25 | */ 26 | let slow = head; 27 | let fast = head; 28 | 29 | if (!(head && head.next)) return null; 30 | 31 | while (fast && fast.next) { 32 | fast = fast.next.next; 33 | 34 | if (!(fast && fast.next)) { 35 | slow.next = slow.next.next; 36 | } 37 | 38 | slow = slow.next; 39 | } 40 | 41 | return head; 42 | }; 43 | // @lc code=end 44 | -------------------------------------------------------------------------------- /链表/2181.合并零之间的节点.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=2181 lang=javascript 3 | * 4 | * [2181] 合并零之间的节点 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @return {ListNode} 18 | */ 19 | var mergeNodes = function (head) { 20 | head = head.next; 21 | let current = head; 22 | 23 | while (current && current.next) { 24 | if (current.next.val !== 0) { 25 | current.val += current.next.val; 26 | current.next = current.next.next; 27 | } else { 28 | current.next = current.next.next; 29 | current = current.next; 30 | } 31 | } 32 | 33 | return head; 34 | }; 35 | // @lc code=end 36 | -------------------------------------------------------------------------------- /链表/23.合并k个升序链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=23 lang=javascript 3 | * 4 | * [23] 合并K个升序链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode[]} lists 17 | * @return {ListNode} 18 | */ 19 | var mergeKLists = function (lists) { 20 | function transform(item, array) { 21 | while (item) { 22 | array.push(item); 23 | item = item.next; 24 | } 25 | } 26 | 27 | const array = []; 28 | let result = new ListNode(null); 29 | 30 | lists.map((item) => transform(item, array)); 31 | array.sort((a, b) => a - b); 32 | 33 | for (let i = array.length - 1; i >= 0; i--) { 34 | const temp = new ListNode(null); 35 | 36 | result.val = array[i]; 37 | temp.next = result; 38 | result = temp; 39 | } 40 | 41 | return result.next; 42 | }; 43 | 44 | // @lc code=end 45 | -------------------------------------------------------------------------------- /链表/234.回文链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=234 lang=javascript 3 | * 4 | * [234] 回文链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @return {boolean} 18 | */ 19 | var isPalindrome = function (head) { 20 | const values = []; 21 | 22 | while (head !== null) { 23 | values.push(head.val); 24 | head = head.next; 25 | } 26 | 27 | let left = 0; 28 | let right = values.length - 1; 29 | 30 | while (left < right) { 31 | if (values[left] !== values[right]) return false; 32 | left++; 33 | right--; 34 | } 35 | 36 | return true; 37 | }; 38 | // @lc code=end 39 | -------------------------------------------------------------------------------- /链表/237.删除链表中的节点.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=237 lang=javascript 3 | * 4 | * [237] 删除链表中的节点 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val) { 11 | * this.val = val; 12 | * this.next = null; 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} node 17 | * @return {void} Do not return anything, modify node in-place instead. 18 | */ 19 | var deleteNode = function (node) { 20 | /** 21 | * @author xun 22 | * @method 23 | * @timeComplexity O(1) 24 | * @spaceComplexity O(1) 25 | */ 26 | node.val = node.next.val; 27 | node.next = node.next.next; 28 | }; 29 | // @lc code=end 30 | -------------------------------------------------------------------------------- /链表/2487.从链表中移除节点.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=2487 lang=javascript 3 | * 4 | * [2487] 从链表中移除节点 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @return {ListNode} 18 | */ 19 | var removeNodes = function (head) { 20 | const stack = []; 21 | let current = head; 22 | 23 | while (current) { 24 | const x = current.val; 25 | 26 | while (stack.length && stack[stack.length - 1] < x) { 27 | stack.pop(); 28 | } 29 | stack.push(x); 30 | current = current.next; 31 | } 32 | 33 | const dummy = new ListNode(0); 34 | 35 | let node = dummy; 36 | 37 | for (const x of stack) { 38 | node.next = new ListNode(x); 39 | node = node.next; 40 | } 41 | 42 | return dummy.next; 43 | }; 44 | // @lc code=end 45 | -------------------------------------------------------------------------------- /链表/2807.在链表中插入最大公约数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=2807 lang=javascript 3 | * 4 | * [2807] 在链表中插入最大公约数 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @return {ListNode} 18 | */ 19 | var insertGreatestCommonDivisors = function (head) { 20 | function commonMeasure(x, y) { 21 | return y === 0 ? x : commonMeasure(y, x % y); 22 | } 23 | 24 | let node = head; 25 | while (node.next !== null) { 26 | node.next = new ListNode(commonMeasure(node.val, node.next.val), node.next); 27 | node = node.next.next; 28 | } 29 | 30 | return head; 31 | }; 32 | // @lc code=end 33 | -------------------------------------------------------------------------------- /链表/328.奇偶链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=328 lang=javascript 3 | * 4 | * [328] 奇偶链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @return {ListNode} 18 | */ 19 | var oddEvenList = function (head) { 20 | /** 21 | * @author xun 22 | * @method 节点分离后合并 23 | * @timeComplexity O(N) 24 | * @spaceComplexity O(1) 25 | */ 26 | 27 | if (!head) return head; 28 | 29 | let evenHead = head.next; 30 | let odd = head; 31 | let even = evenHead; 32 | 33 | while (even !== null && even.next !== null) { 34 | odd.next = even.next; 35 | odd = odd.next; 36 | even.next = odd.next; 37 | even = even.next; 38 | } 39 | 40 | odd.next = evenHead; 41 | 42 | return head; 43 | }; 44 | // @lc code=end 45 | -------------------------------------------------------------------------------- /链表/382.链表随机节点.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=382 lang=javascript 3 | * 4 | * [382] 链表随机节点 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | */ 18 | var Solution = function (head) { 19 | this.list = []; 20 | 21 | while (head !== null) { 22 | this.list.push(head.val); 23 | head = head.next; 24 | } 25 | }; 26 | 27 | /** 28 | * @return {number} 29 | */ 30 | Solution.prototype.getRandom = function () { 31 | return this.list[Math.floor] 32 | }; 33 | 34 | /** 35 | * Your Solution object will be instantiated and called as such: 36 | * var obj = new Solution(head) 37 | * var param_1 = obj.getRandom() 38 | */ 39 | // @lc code=end 40 | -------------------------------------------------------------------------------- /链表/61.旋转链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=61 lang=javascript 3 | * 4 | * [61] 旋转链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @param {number} k 18 | * @return {ListNode} 19 | */ 20 | var rotateRight = function (head, k) { 21 | /** 22 | * @author xun 23 | * @method 闭合为环 24 | * @timeComplexity O(n) 25 | * @spaceComplexity O(1) 26 | */ 27 | 28 | // 边界条件 29 | if (k === 0 || head === null || head.next === null) { 30 | return head; 31 | } 32 | 33 | let n = 1; // 通过遍历知道链表的长度 34 | 35 | let current = head; 36 | while (current.next) { 37 | current = current.next; 38 | n++; 39 | } 40 | 41 | let add = n - (k % n); 42 | 43 | if (add === n) { 44 | // 如果要移动的次数和链表的长度相同则直接返回 45 | return head; 46 | } 47 | 48 | current.next = head; 49 | 50 | while (add) { 51 | current = current.next; 52 | add--; 53 | } 54 | 55 | const result = current.next; // 维护一个变量,最终返回 56 | current.next = null; 57 | 58 | return result; 59 | }; 60 | // @lc code=end 61 | -------------------------------------------------------------------------------- /链表/725.分隔链表.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=725 lang=javascript 3 | * 4 | * [725] 分隔链表 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @param {number} k 18 | * @return {ListNode[]} 19 | */ 20 | var splitListToParts = function (head, k) { 21 | /** 22 | * @author xun 23 | * @method 拆分链表 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(1) 26 | */ 27 | 28 | let n = 0; 29 | let temp = head; 30 | while (temp !== null) { 31 | n++; 32 | temp = temp.next; 33 | } 34 | 35 | let quotient = Math.floor(n / k); 36 | let remainder = n % k; 37 | 38 | const result = new Array(k).fill(null); 39 | let current = head; 40 | for (let i = 0; i < k && current !== null; i++) { 41 | result[i] = current; 42 | let partSize = quotient + (i < remainder ? 1 : 0); 43 | for (let j = 1; j < partSize; j++) { 44 | current = current.next; 45 | } 46 | 47 | const next = current.next; 48 | current.next = null; 49 | current = next; 50 | } 51 | 52 | return result; 53 | }; 54 | // @lc code=end 55 | -------------------------------------------------------------------------------- /链表/817.链表组件.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=817 lang=javascript 3 | * 4 | * [817] 链表组件 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @param {number[]} nums 18 | * @return {number} 19 | */ 20 | var numComponents = function (head, nums) { 21 | /** 22 | * @author xun 23 | * @method 计算组件的起始位置 24 | * @timeComplexity O(N) 25 | * @spaceComplexity O(m) 26 | */ 27 | const set = new Set([...nums]); 28 | 29 | let inSet = false; 30 | let res = 0; 31 | while (head) { 32 | if (set.has(head.val)) { 33 | if (!inSet) { 34 | inSet = true; 35 | res++; 36 | } 37 | } else { 38 | inSet = false; 39 | } 40 | head = head.next; 41 | } 42 | 43 | return res; 44 | }; 45 | // @lc code=end 46 | -------------------------------------------------------------------------------- /链表/83.删除排序链表中的重复元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=83 lang=javascript 3 | * 4 | * [83] 删除排序链表中的重复元素 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @return {ListNode} 18 | */ 19 | var deleteDuplicates = function (head) { 20 | /** 21 | * @author xun 22 | * @method 递归 23 | * @timeComplexity 24 | * @spaceComplexity 25 | */ 26 | // if (head == null || head.next == null) { 27 | // return head; 28 | // } 29 | // head.next = deleteDuplicates(head.next); 30 | // if (head.val === head.next.val) head.next = head.next.next; 31 | // return head; 32 | /** 33 | * @author xun 34 | * @method 一次遍历 35 | * @timeComplexity O(n) 36 | * @spaceComplexity O(1) 37 | */ 38 | if (head === null) return head; 39 | let current = head; 40 | while (current.next) { 41 | if (current.val === current.next.val) { 42 | current.next = current.next.next; 43 | } else { 44 | current = current.next; 45 | } 46 | } 47 | return head; 48 | }; 49 | // @lc c\ode=end 50 | -------------------------------------------------------------------------------- /链表/92.反转链表-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=92 lang=javascript 3 | * 4 | * [92] 反转链表 II 5 | */ 6 | 7 | // @lc code=start 8 | /** 9 | * Definition for singly-linked list. 10 | * function ListNode(val, next) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | */ 15 | /** 16 | * @param {ListNode} head 17 | * @param {number} left 18 | * @param {number} right 19 | * @return {ListNode} 20 | */ 21 | var reverseBetween = function (head, left, right) { 22 | /** 23 | * @author xun 24 | * @method 穿针引线 25 | * @timeComplexity O(N) 26 | * @spaceComplexity O(1) 27 | */ 28 | const dummy = new ListNode(0); 29 | 30 | dummy.next = head; 31 | let previous = dummy; 32 | 33 | for (let i = 0; i < left - 1; i++) { 34 | previous = previous.next; 35 | } 36 | 37 | let current = previous.next; 38 | 39 | for (let i = 0; i < right - left; i++) { 40 | const node = current.next; 41 | current.next = node.next; 42 | node.next = previous.next; 43 | previous.next = node; 44 | } 45 | 46 | return dummy.next; 47 | }; 48 | // @lc code=end 49 | --------------------------------------------------------------------------------