├── .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 |
--------------------------------------------------------------------------------