Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a49086b

Browse files
committedMay 19, 2022
fix: --
1 parent 41f640a commit a49086b

32 files changed

+1314
-28
lines changed
 

‎README.md

Lines changed: 67 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,72 @@
3535

3636
## 🐤 交流讨论 && 如何学习 && 转载声明 && 帮忙修正以及补充
3737

38-
第一:你可以直接在本仓库阅读即可,**阶段性学习**。 (可以转载里面的所有知识点用到任何地方,但请添加仓库的地址)有问题欢迎提交[issues](https://github.com/webVueBlog/Leetcode/issues)
38+
第一:你可以直接在本仓库阅读即可,**阶段性学习**。 (可以转载里面的所有知识点用到任何地方,但请添加仓库的地址)有问题欢迎提交[issues](https://github.com/webVueBlog/Leetcode/issues)
39+
40+
## Leetcode题解
41+
42+
- https://shields.io/
43+
- [leetcode](https://leetcode-cn.com/problemset/all/)
44+
45+
<h1 align="center">👩🏻‍💻:webVueBlog的leetcode刷题📒</h1>
46+
<div align="center">
47+
<img src="https://img.shields.io/badge/-Easy-green">
48+
<img src="https://img.shields.io/badge/-Medium-orange">
49+
<img src="https://img.shields.io/badge/-Hard-red">
50+
</div>
51+
52+
- [1.two-sum](./leetcode/1.two-sum.js)
53+
- [1.两数之和](./leetcode/1.两数之和.js)
54+
- [3.longest-substring-without-repeating-characters](./leetcode/3.longest-substring-without-repeating-characters.js)
55+
- [3.无重复字符的最长子串](./leetcode/3.无重复字符的最长子串.js)
56+
- [7.reverse-integer](./leetcode/7.reverse-integer.js)
57+
- [37.sudoku-solver](./leetcode/37.sudoku-solver.js)
58+
- [43.multiply-strings](./leetcode/43.multiply-strings.js)
59+
- [56.merge-intervals](./leetcode/56.merge-intervals.js)
60+
- [62.unique-paths](./leetcode/62.unique-paths.js)
61+
- [64.minimum-path-sum](./leetcode/64.minimum-path-sum.js)
62+
- [78.子集](./leetcode/78.子集.js)
63+
- [101.symmetric-tree](./leetcode/101.symmetric-tree.js)
64+
- [129.sum-root-to-leaf-numbers](./leetcode/129.sum-root-to-leaf-numbers.js)
65+
- [198.house-robber](./leetcode/198.house-robber.js)
66+
- [206.反转链表](./leetcode/206.反转链表.js)
67+
- [220.contains-duplicate-iii](./leetcode/220.contains-duplicate-iii.js)
68+
- [239.sliding-window-maximum](./leetcode/239.sliding-window-maximum.js)
69+
- [263.ugly-number](./leetcode/263.ugly-number.js)
70+
- [300.longest-increasing-subsequence](./leetcode/300.longest-increasing-subsequence.js)
71+
- [312.burst-balloons](./leetcode/312.burst-balloons.js)
72+
- [415.add-strings](./leetcode/415.add-strings.js)
73+
- [503.next-greater-element-ii](./leetcode/503.next-greater-element-ii.js)
74+
- [674.longest-continuous-increasing-subsequence](./leetcode/674.longest-continuous-increasing-subsequence.js)
75+
- [784.letter-case-permutation](./leetcode/784.letter-case-permutation.js)
76+
- [1312.minimum-insertion-steps-to-make-a-string-palindrome](./leetcode/1312.minimum-insertion-steps-to-make-a-string-palindrome.js)
77+
- [1319.number-of-operations-to-make-network-connected](./leetcode/1319.number-of-operations-to-make-network-connected.js)
78+
- [1338.reduce-array-size-to-the-half](./leetcode/1338.reduce-array-size-to-the-half.js)
79+
- [1343](./leetcode/1343.js)
80+
- [1343.number-of-sub-arrays-of-size-k-and-average-greater-than-or-equal-to-threshold](./leetcode/1343.number-of-sub-arrays-of-size-k-and-average-greater-than-or-equal-to-threshold.js)
81+
- [1432.改变一个整数能得到的最大差值](./leetcode/1432.改变一个整数能得到的最大差值.js)
82+
- [2135.count-words-obtained-after-adding-a-letter](./leetcode/2135.count-words-obtained-after-adding-a-letter.js)
83+
- [戳气球](./leetcode/戳气球.js)
84+
- [存在重复元素III](./leetcode/存在重复元素III.js)
85+
- [二维数组中的查找](./leetcode/二维数组中的查找.js)
86+
- [合并区间](./leetcode/合并区间.js)
87+
- [链表反转](./leetcode/链表反转.js)
88+
- [两数之和](./leetcode/两数之和.js)
89+
- [零钱兑换](./leetcode/零钱兑换.js)
90+
- [前K个高频单词](./leetcode/前K个高频单词.js)
91+
- [青蛙跳台阶问题](./leetcode/青蛙跳台阶问题.js)
92+
- [全排列](./leetcode/全排列.js)
93+
- [全排列II](./leetcode/全排列II.js)
94+
- [三数之和](./leetcode/三数之和.js)
95+
- [下一个更大元素II](./leetcode/下一个更大元素II.js)
96+
- [在排序数组中查找元素的第一个和最后一个位置](./leetcode/在排序数组中查找元素的第一个和最后一个位置.js)
97+
- [字符串相乘](./leetcode/字符串相乘.js)
98+
- [字符串相加](./leetcode/字符串相加.js)
99+
- [组合总和](./leetcode/组合总和.js)
100+
- [最小路径和](./leetcode/最小路径和.js)
101+
- [最长不含重复字符的子字符串](./leetcode/最长不含重复字符的子字符串.js)
102+
- [最长递增子序列](./leetcode/最长递增子序列.js)
103+
- [最长连续递增序列](./leetcode/最长连续递增序列.js)
39104

40105
## 深入手写JS原生API
41106

@@ -1175,33 +1240,7 @@
11751240
- 39.[vue组件设计](./全栈架构师/vue组件设计.md)
11761241
- 40.[Taro框架](./全栈架构师/Taro框架.md)
11771242

1178-
</details>
1179-
1180-
## Leetcode题解
1181-
1182-
- https://shields.io/
1183-
- [leetcode](https://leetcode-cn.com/problemset/all/)
1184-
1185-
<h1 align="center">👩🏻‍💻:webVueBlog的leetcode刷题📒</h1>
1186-
<div align="center">
1187-
<img src="https://img.shields.io/badge/-Easy-green">
1188-
<img src="https://img.shields.io/badge/-Medium-orange">
1189-
<img src="https://img.shields.io/badge/-Hard-red">
1190-
</div>
1191-
1192-
1. `Number`题号
1193-
2. `Title`题目
1194-
3. `Difficulty`难度
1195-
4. `Navigation`解答
1196-
1197-
1198-
| Number | Title | Difficulty | Navigation |
1199-
| :--: | :------: |:------: | :------: |
1200-
| 1. | 两数之和 | <img src="https://img.shields.io/badge/-Easy-green"> | [两数之和](题库/两数之和.md) |
1201-
| 2. | 两数相加 | <img src="https://img.shields.io/badge/-Medium-orange"> | [两数相加](题库/两数相加.md) |
1202-
| 3. | 无重复字符的最长子串 | <img src="https://img.shields.io/badge/-Medium-orange"> | [无重复字符的最长子串](题库/无重复字符的最长子串.md) |
1203-
1204-
以 「早起」、「运动」、「冥想」、「写作」、「阅读」这五件能够快速改变人生的事情为切入点,帮助大家建立良好的生活习惯,技术的成长绝不是一朝一夕,良好的习惯将会帮助我们更快的进步,但在技术之外,我更希望大家能在这些事情的坚持中,收获一份自信,多一份底气,对人生多一份积极。 --- (来源:低调务实优秀中国好青年群)
1243+
</details>
12051244

12061245
## License
12071246
[![MIT](http://api.haizlin.cn/api?mod=interview&ctr=issues&act=generateSVG&type=a.svg)](https://github.com/webVueBlog/interview-answe)

‎code/下一个更大元素II.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {number[]}
4+
503.下一个更大元素II
5+
*/
6+
var nextGreaterElements = function(nums) {
7+
nums = nums.concat(nums);
8+
let len = nums.length;
9+
let oldLen = len / 2;
10+
let stack = [];
11+
let ans = new Array(oldLen).fill(-1)
12+
for (let i = 0; i < len; i++) {
13+
let current = nums[i];
14+
while (stack.length > 0 && current > nums[stack[stack.length - 1]]) {
15+
let topIndex = stack[stack.length - 1];
16+
ans[topIndex % oldLen] = current;
17+
stack.pop();
18+
}
19+
stack.push(i);
20+
}
21+
return ans;
22+
};

‎code/全排列II.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {number[][]}
4+
47.全排列 II #回溯
5+
*/
6+
var permuteUnique = function(nums) {
7+
const dfs = (curr, store, arr, len) => {
8+
if (curr.length === len) {
9+
arr.push([...curr]);
10+
return;
11+
}
12+
for (let i = 0; i < store.length; i++) {
13+
if (i > 0 && store[i] === store[i - 1]) {
14+
continue
15+
}
16+
let select = store[i]
17+
dfs(
18+
curr.concat(select),
19+
store.slice(0, i).concat(store.slice(i + 1)),
20+
arr,
21+
len
22+
)
23+
}
24+
}
25+
let ans = []
26+
nums.sort((a, b) => a - b);
27+
dfs([], nums, ans, nums.length)
28+
return ans
29+
};

‎code/前K个高频单词.js

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/**
2+
* @param {string[]} words
3+
* @param {number} k
4+
* @return {string[]}
5+
692.前K个高频单词 #堆
6+
root: i
7+
left: 2*i+1 right: 2*i+2
8+
9+
知道左边/右边:Math.floor((n-1)/2) => root索引
10+
[2,1,5,6,3,25,30]
11+
2(0) (堆顶是100单词中出现频率最低的),字典序更小
12+
1(1) 5(2)
13+
25(5) 30(6)
14+
加进来的单词,与堆顶进行比较,如果出现的频率比堆顶高,新单词替换旧单词
15+
出现频率变化,在把所有堆变化,把最小频率的放到堆顶
16+
*/
17+
// n堆的长度, map记录单词的出现的频率,堆也是数组
18+
class Heap {
19+
constructor(n, map) {
20+
this.arr = [];
21+
this.max = n;
22+
this.map = map;
23+
}
24+
add(word) {
25+
// 先拿堆
26+
let arr = this.arr;
27+
let len = arr.length;
28+
if(len < this.max) {
29+
this.directAdd(word);
30+
this.rebuild();
31+
} else {
32+
const newWordIsMoreFrequent = !this.compareLow(word, arr[0]);
33+
if(newWordIsMoreFrequent) {
34+
// 频率更高的话
35+
this.arr[0] = word
36+
this.rebuild()
37+
}
38+
}
39+
}
40+
directAdd(word) {
41+
this.arr.push(word)
42+
}
43+
swap(i, j) {
44+
let arr = this.arr;
45+
[arr[i], arr[j]] = [arr[j], arr[i]];
46+
}
47+
rebuild() {
48+
let arr = this.arr
49+
let len = arr.length
50+
let i = Math.floor((len-1)/2)
51+
while(i>=0) {
52+
let l = 2*i + 1;
53+
let r = 2*i + 2;
54+
let root = arr[i];
55+
let left = arr[l];
56+
let right = arr[r];
57+
let temp = i; // 默认根节点最小
58+
let tempWord = root;
59+
if(l < len && this.compareLow(left, tempWord)) {
60+
tempWord = left;
61+
temp = l;
62+
}
63+
if(r < len && this.compareLow(right, tempWord)) {
64+
tempWord = right;
65+
temp = r;
66+
}
67+
// 当前频率最低的就是根节点 ===
68+
// 不相等
69+
if(temp !== i) {
70+
this.swap(temp, i); // 交换单词
71+
}
72+
i--
73+
}
74+
}
75+
compareLow(newWord, oldWord) {
76+
let map = this.map
77+
if(map[newWord] < map[oldWord]) {
78+
return true
79+
}
80+
if(map[newWord] > map[oldWord]) {
81+
return false
82+
}
83+
if(map[newWord] === map[oldWord]) {
84+
return newWord > oldWord
85+
}
86+
}
87+
sort() {
88+
let map = this.map;
89+
this.arr.sort((prev, next) => {
90+
// 按照频率,字典序
91+
// 如果左边的单词出现的频率大于右边的单词
92+
if(map[prev] > map[next]) {
93+
return -1;
94+
}
95+
if(map[prev] < map[next]) {
96+
return 1;
97+
}
98+
if(map[prev] === map[next]) { // 频率一样
99+
return prev > next ? 1 : -1
100+
}
101+
})
102+
}
103+
get result() {
104+
this.sort();
105+
return this.arr
106+
}
107+
}
108+
109+
var topKFrequent = function(words, k) {
110+
let map = {};
111+
words.forEach(word => {
112+
map[word] = map[word] === undefined ? 1 : map[word] + 1;
113+
});
114+
let heap = new Heap(k, map);
115+
// 遍历不重复的单词列表
116+
let wordList = Object.keys(map);
117+
for(let i = 0; i < wordList.length; i++) {
118+
heap.add(wordList[i])
119+
}
120+
return heap.result;
121+
};

‎code/合并区间.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// s1 s2 s1[1] >= s2[0]
2+
// current next
3+
/**
4+
* @param {number[][]} intervals
5+
* @return {number[][]}
6+
56. 合并区间
7+
*/
8+
var merge = function(intervals) {
9+
let ans = []
10+
let len = intervals.length
11+
let index = 0
12+
let current = []
13+
intervals.sort((prev, next) => prev[0] - next[0])
14+
while(index < len) {
15+
next = intervals[index++]
16+
if (current.length === 0) {
17+
current = next
18+
} else {
19+
if(current[1] >= next[0]) {
20+
current = [current[0], Math.max(current[1], next[1])]
21+
}else{
22+
ans.push([...current])
23+
current = next
24+
}
25+
}
26+
}
27+
if(current.length > 0) {
28+
ans.push([...current])
29+
}
30+
return ans
31+
};

‎code/字符串相乘.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
* @param {string} num1
3+
* @param {string} num2
4+
* @return {string}
5+
43. 字符串相乘
6+
*/
7+
var multiply = function(num1, num2) {
8+
let len2 = num2.length;
9+
let sum = []
10+
for (let i = len2 - 1; i >= 0; i--) {
11+
let fill = len2 - i - 1
12+
let product = multi(num1, num2[i], fill)
13+
sum.push(product)
14+
}
15+
let result = sum.reduce((prev, next) => {
16+
return addStrings(prev, next)
17+
})
18+
while (result.length > 1 && result[0] === '0') {
19+
result = result.slice(1)
20+
}
21+
return result
22+
};
23+
24+
function multi(n1, n2, fill) {
25+
fill = fill >= 0 ? fill : 0
26+
let carry = 0
27+
let result = ''
28+
let i = n1.length - 1
29+
while (i >= 0) {
30+
let curr = n1[i]
31+
let product = Number(curr) * Number(n2) + carry;
32+
if (product >= 10) {
33+
let strPro = String(product)
34+
carry = strPro[0] * 1
35+
result = strPro[1] + result
36+
} else {
37+
carry = 0
38+
result = product + result
39+
}
40+
i--
41+
}
42+
if (carry !== 0) {
43+
result = carry + result
44+
}
45+
return result + '0'.repeat(fill)
46+
}
47+
48+
var addStrings = function(num1, num2) {
49+
let len1 = num1.length
50+
let len2 = num2.length
51+
let i = len1 - 1
52+
let j = len2 - 1
53+
let carry = 0
54+
let ans = ''
55+
while (i >= 0 || j >= 0) {
56+
let cur1 = i < 0 ? 0 : num1[i] * 1
57+
let cur2 = j < 0 ? 0 : num2[j] * 1
58+
let { result, nextCarry } = add(cur1, cur2, carry)
59+
carry = nextCarry
60+
ans = result + ans
61+
i--
62+
j--
63+
}
64+
if (carry !== 0) {
65+
ans = carry + ans
66+
}
67+
return ans
68+
}
69+
70+
function add(n1, n2, lastCarry) {
71+
let result = 0
72+
let nextCarry = 0
73+
let num = n1 + n2 + lastCarry
74+
if (num >= 10) {
75+
let strnum = String(num)
76+
result = strnum.slice(1) * 1
77+
nextCarry = strnum.slice(0, 1) * 1
78+
} else {
79+
result = num
80+
}
81+
return {
82+
result,
83+
nextCarry
84+
}
85+
}

‎code/字符串相加.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* @param {string} num1
3+
* @param {string} num2
4+
* @return {string}
5+
415.字符串相加
6+
*/
7+
var addStrings = function(num1, num2) {
8+
let len1 = num1.length
9+
let len2 = num2.length
10+
let i = len1 - 1
11+
let j = len2 - 1
12+
let carry = 0
13+
let ans = ''
14+
while(i>=0 || j>=0) {
15+
let cur1 = i < 0 ? 0 : num1[i] * 1
16+
let cur2 = j < 0 ? 0 : num2[j] * 1
17+
let {result, nextcarry} = add (cur1, cur2, carry)
18+
carry = nextcarry
19+
ans = result + ans
20+
i--
21+
j--
22+
}
23+
if(carry!==0) {
24+
ans = carry + ans
25+
}
26+
return ans
27+
};
28+
29+
function add(n1, n2, lastCarry) {
30+
let result = 0
31+
let nextcarry = 0
32+
let num = n1 + n2 + lastCarry
33+
if(num >= 10) {
34+
let strnum = String(num)
35+
result = strnum.slice(1) * 1
36+
nextcarry = strnum.slice(0,1) * 1
37+
} else {
38+
result = num
39+
}
40+
return {
41+
result,
42+
nextcarry
43+
}
44+
}
45+

‎code/存在重复元素III.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* @param {number[]} nums
3+
* @param {number} k
4+
* @param {number} t
5+
* @return {boolean}
6+
220.存在重复元素III #滑动窗口
7+
*/
8+
var containsNearbyAlmostDuplicate = function(nums, k, t) {
9+
let len = nums.length;
10+
let window = [];
11+
let ans = false;
12+
out: for (let i = 0; i < len; i++) {
13+
let value = nums[i];
14+
for (let j = 0; j < window.length; j++) {
15+
let w = window[j];
16+
if (Math.abs(w - value) <= t) {
17+
ans = true;
18+
break out;
19+
}
20+
}
21+
window.push(value);
22+
if (window.length > k) {
23+
window.shift();
24+
}
25+
}
26+
return ans;
27+
};

‎code/最长连续递增序列.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {number}
4+
674. 最长连续递增序列
5+
*/
6+
var findLengthOfLCIS = function(nums) {
7+
let len = nums.length
8+
let max = 0
9+
let count = 1
10+
for(let i = 0; i < len; i++) {
11+
if(nums[i] < nums[i+1]) {
12+
count++
13+
} else {
14+
max = Math.max(count, max)
15+
count = 1
16+
}
17+
}
18+
return max
19+
};

‎code/最长递增子序列.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// 动态规划,一个完整的问题,它可以分解成很多更小规模的子问题,然后由这些小规模的子问题,小规模问题的最优解,就可以推导出来整个问题的最优解
2+
// 只有你局部做到最优,那么你全局整个问题都是最优的
3+
// 动态规划:状态 + 选择
4+
/**
5+
[10,9,2,5,3,7,101,18]
6+
[10,9,2,5,3,7,101]
7+
[10,9,2,5,3,7] 18 3 + 1 = 4
8+
3
9+
*/
10+
/**
11+
* @param {number[]} nums
12+
* @return {number}
13+
300.最长递增子序列 #动态规划
14+
*/
15+
var lengthOfLIS = function(nums) {
16+
let len = nums.length
17+
let max = 1
18+
let dp = new Array(len).fill(1)
19+
for (let i = 0; i<len; i++) {
20+
for (let j = 0; j < i; j++) {
21+
if(nums[j] <nums[i]) {
22+
dp[i] = Math.max(dp[j] + 1, dp[i])
23+
}
24+
}
25+
max = Math.max(dp[i], max)
26+
}
27+
return max
28+
};

‎leetcode/1343.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* @lc app=leetcode.cn id=1343 lang=javascript
3+
*
4+
* [1343] Number of Sub-arrays of Size K and Average Greater than or Equal to Threshold
5+
*/
6+
7+
// @lc code=start
8+
/**
9+
* @param {number[]} arr
10+
* @param {number} k
11+
* @param {number} threshold
12+
* @return {number}
13+
arr = [2,2,2,2,5,5,5,8], k = 3, threshold = 4
14+
i j
15+
0 j(2) i=k-j-1
16+
3, 4...
17+
k-i-1 i(2)
18+
*/
19+
var numOfSubarrays = function(arr, k, threshold) {
20+
let sum = 0;
21+
const len = arr.length;
22+
let count = 0;
23+
for (let i = 0; i < len; i++) {
24+
sum += arr[i];
25+
if (i >= k) {
26+
sum -= arr[i - k];
27+
}
28+
if (i >= k - 1 && sum / k >= threshold) {
29+
count++;
30+
}
31+
}
32+
return count;
33+
};
34+
// @lc code=end
35+
// @lc code=end

‎leetcode/三数之和.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {number[][]}
4+
15. 三数之和
5+
nums = [-1,0,1,2,-1,-4] [-4,-1,-1, 1, 3, 4, 2]
6+
i i+1 n-1
7+
*/
8+
var threeSum = function(nums) {
9+
nums.sort((x,y) => x-y);
10+
const n = nums.length;
11+
const ans = [];
12+
for(let i=0; i<n; i++) {
13+
let val = nums[i];
14+
if(val > 0) continue;
15+
if(i>0 && val === nums[i-1]) continue;
16+
let l = i + 1;
17+
let r = n - 1;
18+
while(l < r) {
19+
let sum = val + nums[l] + nums[r];
20+
if (sum === 0) {
21+
ans.push([val, nums[l], nums[r]])
22+
while(l<r && nums[l] === nums[l+1]) l++;
23+
while(l<r && nums[r] === nums[r+1]) i--;
24+
l++;
25+
r--;
26+
}else if(sum>0) {
27+
r--;
28+
}else{
29+
l++;
30+
}
31+
}
32+
}
33+
return ans;
34+
};
35+
36+
37+
/**
38+
* @param {number[]} nums
39+
* @return {number[][]}
40+
15. 三数之和
41+
*/
42+
var threeSum = function(nums) {
43+
if(!nums || nums.length < 2) return [];
44+
nums.sort((a, b) => a -b);
45+
let res = [];
46+
for(let i=0; i<nums.length; i++) {
47+
if(nums[i]>0) return res;
48+
if(nums[i-1] === nums[i]) continue;
49+
let [left, right] = [i+1, nums.length - 1];
50+
while(left < right) {
51+
const sum = nums[i] + nums[left] + nums[right];
52+
if(sum === 0) {
53+
res.push([nums[i], nums[left], nums[right]]);
54+
while(left<right && nums[left] === nums[left+1]) left++;
55+
while(left<right && nums[right] === nums[right+1]) right--;
56+
left++;''
57+
right--;
58+
} else if( sum < 0) {
59+
left++;
60+
} else {
61+
right--;
62+
}
63+
}
64+
}
65+
return res;
66+
};

‎leetcode/下一个更大元素II.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {number[]}
4+
503.下一个更大元素II
5+
*/
6+
var nextGreaterElements = function(nums) {
7+
nums = nums.concat(nums);
8+
let len = nums.length;
9+
let oldLen = len / 2;
10+
let stack = [];
11+
let ans = new Array(oldLen).fill(-1)
12+
for (let i = 0; i < len; i++) {
13+
let current = nums[i];
14+
while (stack.length > 0 && current > nums[stack[stack.length - 1]]) {
15+
let topIndex = stack[stack.length - 1];
16+
ans[topIndex % oldLen] = current;
17+
stack.pop();
18+
}
19+
stack.push(i);
20+
}
21+
return ans;
22+
};

‎leetcode/两数之和.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* @param {number[]} nums
3+
* @param {number} target
4+
* @return {number[]}
5+
*/
6+
var twoSum = function(nums, target) {
7+
let result = [];
8+
let mapArr = new Map();
9+
for(let i = 0; i < nums.length; i++) {
10+
mapArr.set(nums[i], i) // { 3, 0 } { 2, 1 } { 4, 2}
11+
for(let j = 0; j < nums.length; j++) {
12+
let diff = target - nums[j]; // 6 - 3(0) = 3 / 6 - 2(1) = 4
13+
if (mapArr.has(diff) && mapArr.get(diff) !== j) {
14+
result[0] = mapArr.get(diff);
15+
result[1] = j;
16+
}
17+
}
18+
}
19+
return result;
20+
};

‎leetcode/二维数组中的查找.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @param {number[][]} matrix
3+
* @param {number} target
4+
* @return {boolean}
5+
剑指 Offer 04. 二维数组中的查找
6+
*/
7+
var findNumberIn2DArray = function(matrix, target) {
8+
if(matrix.length === 0 || matrix[0].length===0) return false;
9+
const row = matrix.length;
10+
const col = matrix[0].length;
11+
let i = 0,
12+
j = col -1;
13+
while(j>=0 && i<=row-1) {
14+
let value = matrix[i][j]
15+
if(target === value) return true
16+
if(target>value) {
17+
i++;
18+
} else if(target < value) {
19+
j--;
20+
}
21+
}
22+
return false;
23+
};

‎leetcode/全排列.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {number[][]}
4+
46. 全排列
5+
[1,2,3] length=3 []
6+
*/
7+
var permute = function(nums) {
8+
const dfs = (curr, store) => {
9+
// 1.满足条件,记录结果
10+
// 2.满足终止条件,立即终止
11+
if(curr.length===nums.length) {
12+
ans.push([...curr]);
13+
// store.length === 0
14+
return;
15+
}
16+
// 3.继续尝试
17+
for(let i=0; i<store.length; i++) {
18+
// i=0 i=1 i=2
19+
//[] [1, 2, 3]
20+
//[2] [1,3]
21+
dfs(
22+
curr.concat(store[i]),
23+
store.slice(0,i).concat(store.slice(i+1))
24+
)
25+
}
26+
};
27+
let ans = [];
28+
dfs([], nums);
29+
return ans;
30+
};

‎leetcode/全排列II.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {number[][]}
4+
47.全排列 II #回溯
5+
*/
6+
var permuteUnique = function(nums) {
7+
const dfs = (curr, store, arr, len) => {
8+
if (curr.length === len) {
9+
arr.push([...curr]);
10+
return;
11+
}
12+
for (let i = 0; i < store.length; i++) {
13+
if (i > 0 && store[i] === store[i - 1]) {
14+
continue
15+
}
16+
let select = store[i]
17+
dfs(
18+
curr.concat(select),
19+
store.slice(0, i).concat(store.slice(i + 1)),
20+
arr,
21+
len
22+
)
23+
}
24+
}
25+
let ans = []
26+
nums.sort((a, b) => a - b);
27+
dfs([], nums, ans, nums.length)
28+
return ans
29+
};

‎leetcode/前K个高频单词.js

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/**
2+
* @param {string[]} words
3+
* @param {number} k
4+
* @return {string[]}
5+
692.前K个高频单词 #堆
6+
root: i
7+
left: 2*i+1 right: 2*i+2
8+
9+
知道左边/右边:Math.floor((n-1)/2) => root索引
10+
[2,1,5,6,3,25,30]
11+
2(0) (堆顶是100单词中出现频率最低的),字典序更小
12+
1(1) 5(2)
13+
25(5) 30(6)
14+
加进来的单词,与堆顶进行比较,如果出现的频率比堆顶高,新单词替换旧单词
15+
出现频率变化,在把所有堆变化,把最小频率的放到堆顶
16+
*/
17+
// n堆的长度, map记录单词的出现的频率,堆也是数组
18+
class Heap {
19+
constructor(n, map) {
20+
this.arr = [];
21+
this.max = n;
22+
this.map = map;
23+
}
24+
add(word) {
25+
// 先拿堆
26+
let arr = this.arr;
27+
let len = arr.length;
28+
if(len < this.max) {
29+
this.directAdd(word);
30+
this.rebuild();
31+
} else {
32+
const newWordIsMoreFrequent = !this.compareLow(word, arr[0]);
33+
if(newWordIsMoreFrequent) {
34+
// 频率更高的话
35+
this.arr[0] = word
36+
this.rebuild()
37+
}
38+
}
39+
}
40+
directAdd(word) {
41+
this.arr.push(word)
42+
}
43+
swap(i, j) {
44+
let arr = this.arr;
45+
[arr[i], arr[j]] = [arr[j], arr[i]];
46+
}
47+
rebuild() {
48+
let arr = this.arr
49+
let len = arr.length
50+
let i = Math.floor((len-1)/2)
51+
while(i>=0) {
52+
let l = 2*i + 1;
53+
let r = 2*i + 2;
54+
let root = arr[i];
55+
let left = arr[l];
56+
let right = arr[r];
57+
let temp = i; // 默认根节点最小
58+
let tempWord = root;
59+
if(l < len && this.compareLow(left, tempWord)) {
60+
tempWord = left;
61+
temp = l;
62+
}
63+
if(r < len && this.compareLow(right, tempWord)) {
64+
tempWord = right;
65+
temp = r;
66+
}
67+
// 当前频率最低的就是根节点 ===
68+
// 不相等
69+
if(temp !== i) {
70+
this.swap(temp, i); // 交换单词
71+
}
72+
i--
73+
}
74+
}
75+
compareLow(newWord, oldWord) {
76+
let map = this.map
77+
if(map[newWord] < map[oldWord]) {
78+
return true
79+
}
80+
if(map[newWord] > map[oldWord]) {
81+
return false
82+
}
83+
if(map[newWord] === map[oldWord]) {
84+
return newWord > oldWord
85+
}
86+
}
87+
sort() {
88+
let map = this.map;
89+
this.arr.sort((prev, next) => {
90+
// 按照频率,字典序
91+
// 如果左边的单词出现的频率大于右边的单词
92+
if(map[prev] > map[next]) {
93+
return -1;
94+
}
95+
if(map[prev] < map[next]) {
96+
return 1;
97+
}
98+
if(map[prev] === map[next]) { // 频率一样
99+
return prev > next ? 1 : -1
100+
}
101+
})
102+
}
103+
get result() {
104+
this.sort();
105+
return this.arr
106+
}
107+
}
108+
109+
var topKFrequent = function(words, k) {
110+
let map = {};
111+
words.forEach(word => {
112+
map[word] = map[word] === undefined ? 1 : map[word] + 1;
113+
});
114+
let heap = new Heap(k, map);
115+
// 遍历不重复的单词列表
116+
let wordList = Object.keys(map);
117+
for(let i = 0; i < wordList.length; i++) {
118+
heap.add(wordList[i])
119+
}
120+
return heap.result;
121+
};

‎leetcode/合并区间.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// s1 s2 s1[1] >= s2[0]
2+
// current next
3+
/**
4+
* @param {number[][]} intervals
5+
* @return {number[][]}
6+
56. 合并区间
7+
*/
8+
var merge = function(intervals) {
9+
let ans = []
10+
let len = intervals.length
11+
let index = 0
12+
let current = []
13+
intervals.sort((prev, next) => prev[0] - next[0])
14+
while(index < len) {
15+
next = intervals[index++]
16+
if (current.length === 0) {
17+
current = next
18+
} else {
19+
if(current[1] >= next[0]) {
20+
current = [current[0], Math.max(current[1], next[1])]
21+
}else{
22+
ans.push([...current])
23+
current = next
24+
}
25+
}
26+
}
27+
if(current.length > 0) {
28+
ans.push([...current])
29+
}
30+
return ans
31+
};
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* @param {number[]} nums
3+
* @param {number} target
4+
* @return {number[]}
5+
34. 在排序数组中查找元素的第一个和最后一个位置
6+
*/
7+
var searchRange = function(nums, target) {
8+
let ans = new Array(2).fill(-1);
9+
nums = nums.sort((a,b) => a - b);
10+
let startIndex = nums.findIndex(value => value === target)
11+
if(startIndex !== -1) {
12+
ans[0] = startIndex
13+
let endIndex = nums.lastIndexOf(target)
14+
if(endIndex !== -1) {
15+
ans[1] = endIndex
16+
}
17+
}
18+
return ans;
19+
};

‎leetcode/字符串相乘.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
* @param {string} num1
3+
* @param {string} num2
4+
* @return {string}
5+
43. 字符串相乘
6+
*/
7+
var multiply = function(num1, num2) {
8+
let len2 = num2.length;
9+
let sum = []
10+
for (let i = len2 - 1; i >= 0; i--) {
11+
let fill = len2 - i - 1
12+
let product = multi(num1, num2[i], fill)
13+
sum.push(product)
14+
}
15+
let result = sum.reduce((prev, next) => {
16+
return addStrings(prev, next)
17+
})
18+
while (result.length > 1 && result[0] === '0') {
19+
result = result.slice(1)
20+
}
21+
return result
22+
};
23+
24+
function multi(n1, n2, fill) {
25+
fill = fill >= 0 ? fill : 0
26+
let carry = 0
27+
let result = ''
28+
let i = n1.length - 1
29+
while (i >= 0) {
30+
let curr = n1[i]
31+
let product = Number(curr) * Number(n2) + carry;
32+
if (product >= 10) {
33+
let strPro = String(product)
34+
carry = strPro[0] * 1
35+
result = strPro[1] + result
36+
} else {
37+
carry = 0
38+
result = product + result
39+
}
40+
i--
41+
}
42+
if (carry !== 0) {
43+
result = carry + result
44+
}
45+
return result + '0'.repeat(fill)
46+
}
47+
48+
var addStrings = function(num1, num2) {
49+
let len1 = num1.length
50+
let len2 = num2.length
51+
let i = len1 - 1
52+
let j = len2 - 1
53+
let carry = 0
54+
let ans = ''
55+
while (i >= 0 || j >= 0) {
56+
let cur1 = i < 0 ? 0 : num1[i] * 1
57+
let cur2 = j < 0 ? 0 : num2[j] * 1
58+
let { result, nextCarry } = add(cur1, cur2, carry)
59+
carry = nextCarry
60+
ans = result + ans
61+
i--
62+
j--
63+
}
64+
if (carry !== 0) {
65+
ans = carry + ans
66+
}
67+
return ans
68+
}
69+
70+
function add(n1, n2, lastCarry) {
71+
let result = 0
72+
let nextCarry = 0
73+
let num = n1 + n2 + lastCarry
74+
if (num >= 10) {
75+
let strnum = String(num)
76+
result = strnum.slice(1) * 1
77+
nextCarry = strnum.slice(0, 1) * 1
78+
} else {
79+
result = num
80+
}
81+
return {
82+
result,
83+
nextCarry
84+
}
85+
}

‎leetcode/字符串相加.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* @param {string} num1
3+
* @param {string} num2
4+
* @return {string}
5+
415.字符串相加
6+
*/
7+
var addStrings = function(num1, num2) {
8+
let len1 = num1.length
9+
let len2 = num2.length
10+
let i = len1 - 1
11+
let j = len2 - 1
12+
let carry = 0
13+
let ans = ''
14+
while(i>=0 || j>=0) {
15+
let cur1 = i < 0 ? 0 : num1[i] * 1
16+
let cur2 = j < 0 ? 0 : num2[j] * 1
17+
let {result, nextcarry} = add (cur1, cur2, carry)
18+
carry = nextcarry
19+
ans = result + ans
20+
i--
21+
j--
22+
}
23+
if(carry!==0) {
24+
ans = carry + ans
25+
}
26+
return ans
27+
};
28+
29+
function add(n1, n2, lastCarry) {
30+
let result = 0
31+
let nextcarry = 0
32+
let num = n1 + n2 + lastCarry
33+
if(num >= 10) {
34+
let strnum = String(num)
35+
result = strnum.slice(1) * 1
36+
nextcarry = strnum.slice(0,1) * 1
37+
} else {
38+
result = num
39+
}
40+
return {
41+
result,
42+
nextcarry
43+
}
44+
}
45+

‎leetcode/存在重复元素III.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* @param {number[]} nums
3+
* @param {number} k
4+
* @param {number} t
5+
* @return {boolean}
6+
220.存在重复元素III #滑动窗口
7+
*/
8+
var containsNearbyAlmostDuplicate = function(nums, k, t) {
9+
let len = nums.length;
10+
let window = [];
11+
let ans = false;
12+
out: for (let i = 0; i < len; i++) {
13+
let value = nums[i];
14+
for (let j = 0; j < window.length; j++) {
15+
let w = window[j];
16+
if (Math.abs(w - value) <= t) {
17+
ans = true;
18+
break out;
19+
}
20+
}
21+
window.push(value);
22+
if (window.length > k) {
23+
window.shift();
24+
}
25+
}
26+
return ans;
27+
};

‎leetcode/戳气球.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {number}
4+
312. 戳气球
5+
1 [3, 8]
6+
7+
[1,3,1,5,8,1]
8+
0 1 2 3 4 5
9+
-------
10+
- start
11+
-------- 1->5 有气球2 / 3 / 4 (k的可能值)
12+
(0,3)起始 结束 i->j 最后k
13+
dp[0][3][k] = dp[0][k] + dp[k][3] + nums[0] * nums[k] * nums[3]
14+
dp[i][j][k] = dp[i][k] + dp[k][j] + nums[i] * nums[k] * nums[j]
15+
// 遍历k 尝试 有气球就可以
16+
开区间
17+
dp[0][2][?]
18+
dp[0][5][?]
19+
20+
[3,1,5,8]
21+
0 1 2 3
22+
23+
dp[0][1] + nums[-1] * nums[2] * nums[len] + dp[3][3]
24+
25+
dp[0][1] ?
26+
dp[0][0]
27+
dp[1][1]
28+
dp[3][3] ?
29+
30+
dp[0][3][?] = Math.coin;
31+
*/
32+
var maxCoins = function(nums) {
33+
nums = [1, ...nums, 1];
34+
let len = nums.length;
35+
let dp = new Array(len).fill(0).map(_ => new Array(len).fill(0));
36+
for(let i = len - 3; i >= 0; i--) {
37+
for(let j = i + 2; j < len; j++) {
38+
//1->5 2 / 3 / 4
39+
for(let k = i + 1; k < j; k++) {
40+
dp[i][j] = Math.max(
41+
dp[i][j],
42+
dp[i][k] + dp[k][j] + nums[i] * nums[k] * nums[j]
43+
);
44+
}
45+
}
46+
}
47+
return dp[0][len-1];
48+
};
49+
50+

‎leetcode/最小路径和.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* @param {number[][]} grid
3+
* @return {number}
4+
* dp[i][j] = minSum?
5+
* dp[i][j] = Math.min(dp[i-1][j] + grid[i][j], dp[i][j-1] + grid[i][j])
6+
7+
Infinity Infinity Infinity
8+
Infinity[1, 4, 5]
9+
Infinity[2, 7, 6]
10+
Infinity[6, 8, 7]
11+
12+
*/
13+
var minPathSum = function(grid) {
14+
const row = grid.length;
15+
const col = grid[0].length;
16+
const dp = new Array(row).fill(0).map(_ => new Array(col).fill(0));
17+
dp[0][0] = grid[0][0];
18+
dp[-1] = new Array(col).fill(Infinity);
19+
for (let i = 0; i < row; i++) {
20+
dp[i][-1] = Infinity;
21+
}
22+
for (let i = 0; i < row; i++) {
23+
for (let j = 0; j < col; j++) {
24+
if (i === 0 && j === 0) continue;
25+
dp[i][j] = Math.min(dp[i - 1][j] + grid[i][j], dp[i][j - 1] + grid[i][j]);
26+
}
27+
}
28+
console.log(dp);
29+
return dp[row - 1][col - 1];
30+
};
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* @param {string} s
3+
* @return {number}
4+
剑指 Offer 48. 最长不含重复字符的子字符串
5+
"abcabcbb"
6+
*/
7+
var lengthOfLongestSubstring = function(s) {
8+
const n = s.length;
9+
let i = 0;
10+
let max = 0;
11+
let window = [];
12+
while(i<n) {
13+
let index = window.indexOf(s[i]);
14+
if(index!==-1){
15+
window.splice(0,index+1);
16+
}
17+
window.push(s[i]);
18+
max=Math.max(max, window.length);
19+
i++;
20+
}
21+
return max;
22+
};

‎leetcode/最长连续递增序列.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {number}
4+
674. 最长连续递增序列
5+
*/
6+
var findLengthOfLCIS = function(nums) {
7+
let len = nums.length
8+
let max = 0
9+
let count = 1
10+
for(let i = 0; i < len; i++) {
11+
if(nums[i] < nums[i+1]) {
12+
count++
13+
} else {
14+
max = Math.max(count, max)
15+
count = 1
16+
}
17+
}
18+
return max
19+
};

‎leetcode/最长递增子序列.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// 动态规划,一个完整的问题,它可以分解成很多更小规模的子问题,然后由这些小规模的子问题,小规模问题的最优解,就可以推导出来整个问题的最优解
2+
// 只有你局部做到最优,那么你全局整个问题都是最优的
3+
// 动态规划:状态 + 选择
4+
/**
5+
[10,9,2,5,3,7,101,18]
6+
[10,9,2,5,3,7,101]
7+
[10,9,2,5,3,7] 18 3 + 1 = 4
8+
3
9+
*/
10+
/**
11+
* @param {number[]} nums
12+
* @return {number}
13+
300.最长递增子序列 #动态规划
14+
*/
15+
var lengthOfLIS = function(nums) {
16+
let len = nums.length
17+
let max = 1
18+
let dp = new Array(len).fill(1)
19+
for (let i = 0; i<len; i++) {
20+
for (let j = 0; j < i; j++) {
21+
if(nums[j] <nums[i]) {
22+
dp[i] = Math.max(dp[j] + 1, dp[i])
23+
}
24+
}
25+
max = Math.max(dp[i], max)
26+
}
27+
return max
28+
};

‎leetcode/组合总和.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* @param {number[]} nums
3+
* @param {number} target
4+
* @return {number}
5+
377. 组合总和 Ⅳ
6+
target = 4
7+
dp[4] 和为4的组合数
8+
dp[4] = dp[3]+1 + dp[2]+2 + dp[1]+3 + dp[0]+4
9+
[
10+
[1,1,1]
11+
[1,2]
12+
]
13+
输入:nums = [1,2,3], target = 4
14+
15+
d[4] = dp[3]+1 + dp[2]+2 + dp[1]+3 + dp[0]+4 (4没有出现)
16+
4 + 2 + 1 = 7
17+
d[3] = dp[2]+1 + dp[1]+2 + dp[0]+3
18+
2 + 1 + 1 = 4
19+
dp[2] = dp[1]+1 + dp[0]+2
20+
1 + 1 = 2
21+
dp[1] = dp[0]+1 // dp[1] = 1
22+
1 = 1
23+
dp[0] = 1
24+
25+
输入:nums = [1,2,3], target = 4
26+
27+
dp[4] = 4 + 2 + 1 = 7
28+
= dp[3] + dp[2] + dp[1] = 7
29+
dp[3] = 2 + 1 + 1 = 4
30+
= dp[2] + dp[1] + dp[0] = 4
31+
dp[2] = 1 + 1 = 2
32+
= dp[1] + dp[0] = 2
33+
dp[1] = 1
34+
= dp[0] = 1
35+
dp[0] = 1
36+
37+
38+
*/
39+
var combinationSum4 = function(nums, target) {
40+
let dp = new Array(target+1).fill(0);
41+
dp[0] = 1;
42+
for(let i = 1; i<=target; i++) {
43+
for(let j = 0; j < nums.length; j++) {
44+
if(i - nums[j] >= 0) {
45+
dp[i] += dp[i-nums[j]];
46+
}
47+
}
48+
}
49+
return dp[target];
50+
};
51+
52+
53+

‎leetcode/链表反转.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
## 链表反转
2+
3+
将单链表的链接顺序反转过来
4+
5+
例如:输入:1->2->3->4->5
6+
7+
输出:5->4->3->2->1
8+
9+
使用两种方式解题
10+
11+
<img src="../assets/1641404154990.jpg" style="display: flex; margin: auto; width: 60%;"/>
12+
13+
```js
14+
/**
15+
*
16+
* @param head 链表头部
17+
* @return 返回倒序后的链表头部
18+
*/
19+
public static ListNode iterate(ListNode head){
20+
ListNode prev=null;
21+
ListNode next;
22+
ListNode current = head;
23+
while (current != null){
24+
next = current.next; //保存下一个
25+
current.next = prev; //当前连接上一个
26+
prev = current; //将上一个后移
27+
current = next; //将当前后移
28+
}
29+
return prev;
30+
}
31+
```

‎leetcode/零钱兑换.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* @param {number[]} coins
3+
* @param {number} amount
4+
* @return {number}
5+
322. 零钱兑换
6+
coins = [1, 2, 5], amount = 11
7+
dp[11] = ?
8+
// 从左到右 dp[0] dp[1] dp[2] dp[3]
9+
i 总金额 最少的硬币个数
10+
dp[i] = Math.min(dp[i-coin] + 1, dp[i-coin] + 1...) // icon值
11+
dp[11] = dp[6] + (5) / dp[9] + (2) / dp[10] + (1)
12+
1 1 1
13+
总金额为6的硬币数量
14+
dp[6] dp[9] dp[10]
15+
dp[6] = dp[1] + (5) / dp[4] + (2) / dp[5] + (1)
16+
dp[1] dp[4] dp[5]
17+
dp[1] = dp[-4] + (5) / dp[-1] + (2) / dp[0] + 1
18+
dp[0] dp[i] >= 0
19+
*/
20+
var coinChange = function(coins, amount) {
21+
const dp = new Array(amount+1).fill(Infinity);
22+
dp[0] = 0;
23+
for (let i = 1; i <= amount; i++) {
24+
// dp[1] - dp[11]
25+
for (let coin of coins) {
26+
if (i - coin < 0) continue
27+
dp[i] = Math.min(dp[i], dp[i-coin] + 1)
28+
}
29+
}
30+
return dp[amount] === Infinity ? -1 : dp[amount]; // 硬币数量
31+
};

‎leetcode/青蛙跳台阶问题.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @param {number} n
3+
* @return {number}
4+
剑指 Offer 10- II. 青蛙跳台阶问题
5+
*/
6+
// 1,1,2,3,5,8,13
7+
// 0,1,2,3,4,5
8+
// dp[i] = 7 dp[i] = dp[i-1] + dp[i-2]
9+
// dp[6] = dp[5] + dp[4]
10+
// dp[5] = dp[4] + dp[3] ...
11+
// d[2] = dp[1] + dp[0]
12+
// dp[1] = dp[0] + dp[-1]
13+
// dp[0] = 1
14+
var numWays = function(n) {
15+
const dp = new Array(n);
16+
const mod = 1e9+7;
17+
dp[-1]=0;
18+
dp[0]=1;
19+
for(let i=1; i<=n; i++){
20+
dp[i] = (dp[i-1] + dp[i-2]) % mod;
21+
}
22+
return dp[n];
23+
};

0 commit comments

Comments
 (0)
Please sign in to comment.