Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit bd1bca9

Browse files
Merge branch 'master' into master
2 parents 6776ecc + 7fdb784 commit bd1bca9

39 files changed

+1989
-691
lines changed

‎README.md

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -299,24 +299,25 @@
299299
<img src='https://code-thinking.cdn.bcebos.com/pics/动态规划-背包问题总结.png' width=500 alt='背包问题大纲'> </img></div>
300300

301301

302-
11. [动态规划:01背包理论基础](./problems/背包理论基础01背包-1.md)
303-
12. [动态规划:01背包理论基础(滚动数组)](./problems/背包理论基础01背包-2.md)
302+
11. [动态规划:01背包理论基础(二维dp数组)](./problems/背包理论基础01背包-1.md)
303+
12. [动态规划:01背包理论基础(一维dp数组)](./problems/背包理论基础01背包-2.md)
304304
13. [动态规划:416.分割等和子集](./problems/0416.分割等和子集.md)
305305
14. [动态规划:1049.最后一块石头的重量II](./problems/1049.最后一块石头的重量II.md)
306306
15. [本周小结!(动态规划系列三)](./problems/周总结/20210121动规周末总结.md)
307307
16. [动态规划:494.目标和](./problems/0494.目标和.md)
308308
17. [动态规划:474.一和零](./problems/0474.一和零.md)
309-
18. [动态规划:完全背包总结篇](./problems/背包问题理论基础完全背包.md)
310-
19. [动态规划:518.零钱兑换II](./problems/0518.零钱兑换II.md)
311-
20. [本周小结!(动态规划系列四)](./problems/周总结/20210128动规周末总结.md)
312-
21. [动态规划:377.组合总和IV](./problems/0377.组合总和IV.md)
313-
22. [动态规划:70.爬楼梯(完全背包版本)](./problems/0070.爬楼梯完全背包版本.md)
314-
23. [动态规划:322.零钱兑换](./problems/0322.零钱兑换.md)
315-
24. [动态规划:279.完全平方数](./problems/0279.完全平方数.md)
316-
25. [本周小结!(动态规划系列五)](./problems/周总结/20210204动规周末总结.md)
317-
26. [动态规划:139.单词拆分](./problems/0139.单词拆分.md)
318-
27. [动态规划:多重背包理论基础](./problems/背包问题理论基础多重背包.md)
319-
28. [背包问题总结篇](./problems/背包总结篇.md)
309+
18. [动态规划:完全背包理论基础(二维dp数组)](./problems/背包问题理论基础完全背包.md)
310+
19. [动态规划:完全背包理论基础(一维dp数组)](./problems/背包问题完全背包一维.md)
311+
20. [动态规划:518.零钱兑换II](./problems/0518.零钱兑换II.md)
312+
21. [本周小结!(动态规划系列四)](./problems/周总结/20210128动规周末总结.md)
313+
22. [动态规划:377.组合总和IV](./problems/0377.组合总和IV.md)
314+
23. [动态规划:70.爬楼梯(完全背包版本)](./problems/0070.爬楼梯完全背包版本.md)
315+
24. [动态规划:322.零钱兑换](./problems/0322.零钱兑换.md)
316+
25. [动态规划:279.完全平方数](./problems/0279.完全平方数.md)
317+
26. [本周小结!(动态规划系列五)](./problems/周总结/20210204动规周末总结.md)
318+
27. [动态规划:139.单词拆分](./problems/0139.单词拆分.md)
319+
28. [动态规划:多重背包理论基础](./problems/背包问题理论基础多重背包.md)
320+
29. [背包问题总结篇](./problems/背包总结篇.md)
320321

321322
打家劫舍系列:
322323

@@ -408,21 +409,6 @@
408409

409410
(持续更新中....)
410411

411-
412-
## 十大排序
413-
414-
## 数论
415-
416-
## 高级数据结构经典题目
417-
418-
* 并查集
419-
* 最小生成树
420-
* 线段树
421-
* 树状数组
422-
* 字典树
423-
424-
## 海量数据处理
425-
426412
# 补充题目
427413

428414
以上题目是重中之重,大家至少要刷两遍以上才能彻底理解,如果熟练以上题目之后还在找其他题目练手,可以再刷以下题目:

‎problems/0015.三数之和.md

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
### 哈希解法
3636

37-
两层for循环就可以确定 a 和b 的数值了,可以使用哈希法来确定 0-(a+b) 是否在 数组里出现过,其实这个思路是正确的,但是我们有一个非常棘手的问题,就是题目中说的不可以包含重复的三元组。
37+
两层for循环就可以确定 两个数值,可以使用哈希法来确定 第三个数 0-(a+b) 或者 0 - (a + c) 是否在 数组里出现过,其实这个思路是正确的,但是我们有一个非常棘手的问题,就是题目中说的不可以包含重复的三元组。
3838

3939
把符合条件的三元组放进vector中,然后再去重,这样是非常费时的,很容易超时,也是这道题目通过率如此之低的根源所在。
4040

@@ -48,35 +48,41 @@
4848
```CPP
4949
class Solution {
5050
public:
51+
// 在一个数组中找到3个数形成的三元组,它们的和为0,不能重复使用(三数下标互不相同),且三元组不能重复。
52+
// b(存储)== 0-(a+c)(检索)
5153
vector<vector<int>> threeSum(vector<int>& nums) {
5254
vector<vector<int>> result;
5355
sort(nums.begin(), nums.end());
54-
// 找出a + b + c = 0
55-
// a = nums[i], b = nums[j], c = -(a + b)
56+
5657
for (int i = 0; i < nums.size(); i++) {
57-
// 排序之后如果第一个元素已经大于零,那么不可能凑成三元组
58-
if (nums[i] > 0) {
58+
// 如果a是正数,a<b<c,不可能形成和为0的三元组
59+
if (nums[i] > 0)
5960
break;
60-
}
61-
if (i > 0 && nums[i] == nums[i - 1]) { //三元组元素a去重
61+
62+
// [a, a, ...] 如果本轮a和上轮a相同,那么找到的b,c也是相同的,所以去重a
63+
if (i > 0 && nums[i] == nums[i - 1])
6264
continue;
63-
}
65+
66+
// 这个set的作用是存储b
6467
unordered_set<int> set;
65-
for (int j = i + 1; j < nums.size(); j++) {
66-
if (j > i + 2
67-
&& nums[j] == nums[j-1]
68-
&& nums[j-1] == nums[j-2]) { // 三元组元素b去重
68+
69+
for (int k = i + 1; k < nums.size(); k++) {
70+
// 去重b=c时的b和c
71+
if (k > i + 2 && nums[k] == nums[k - 1]&& nums[k - 1] == nums[k - 2])
6972
continue;
73+
74+
// a+b+c=0 <=> b=0-(a+c)
75+
int target = 0 - (nums[i] + nums[k]);
76+
if (set.find(target) != set.end()) {
77+
result.push_back({nums[i], target, nums[k]}); // nums[k]成为c
78+
set.erase(target);
7079
}
71-
int c = 0 - (nums[i] + nums[j]);
72-
if (set.find(c) != set.end()) {
73-
result.push_back({nums[i], nums[j], c});
74-
set.erase(c);// 三元组元素c去重
75-
} else {
76-
set.insert(nums[j]);
80+
else {
81+
set.insert(nums[k]); // nums[k]成为b
7782
}
7883
}
7984
}
85+
8086
return result;
8187
}
8288
};

‎problems/0019.删除链表的倒数第N个节点.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858

5959
* fast和slow同时移动,直到fast指向末尾,如题:
6060
<img src='https://code-thinking.cdn.bcebos.com/pics/19.%E5%88%A0%E9%99%A4%E9%93%BE%E8%A1%A8%E7%9A%84%E5%80%92%E6%95%B0%E7%AC%ACN%E4%B8%AA%E8%8A%82%E7%82%B92.png' width=600> </img></div>
61-
61+
//图片中有错别词:应该将"只到"改为"直到"
6262
* 删除slow指向的下一个节点,如图:
6363
<img src='https://code-thinking.cdn.bcebos.com/pics/19.%E5%88%A0%E9%99%A4%E9%93%BE%E8%A1%A8%E7%9A%84%E5%80%92%E6%95%B0%E7%AC%ACN%E4%B8%AA%E8%8A%82%E7%82%B93.png' width=600> </img></div>
6464

‎problems/0028.实现strStr.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,6 +1456,70 @@ public int[] GetNext(string needle)
14561456
}
14571457
```
14581458

1459+
### C:
1460+
1461+
> 前缀表统一右移和减一
1462+
1463+
```c
1464+
1465+
int *build_next(char* needle, int len) {
1466+
1467+
int *next = (int *)malloc(len * sizeof(int));
1468+
assert(next); // 确保分配成功
1469+
1470+
// 初始化next数组
1471+
next[0] = -1; // next[0] 设置为 -1,表示没有有效前缀匹配
1472+
if (len <= 1) { // 如果模式串长度小于等于 1,直接返回
1473+
return next;
1474+
}
1475+
next[1] = 0; // next[1] 设置为 0,表示第一个字符没有公共前后缀
1476+
1477+
// 构建next数组, i 从模式串的第三个字符开始, j 指向当前匹配的最长前缀长度
1478+
int i = 2, j = 0;
1479+
while (i < len) {
1480+
if (needle[i - 1] == needle[j]) {
1481+
j++;
1482+
next[i] = j;
1483+
i++;
1484+
} else if (j > 0) {
1485+
// 如果不匹配且 j > 0, 回退到次长匹配前缀的长度
1486+
j = next[j];
1487+
} else {
1488+
next[i] = 0;
1489+
i++;
1490+
}
1491+
}
1492+
return next;
1493+
}
1494+
1495+
int strStr(char* haystack, char* needle) {
1496+
1497+
int needle_len = strlen(needle);
1498+
int haystack_len = strlen(haystack);
1499+
1500+
int *next = build_next(needle, needle_len);
1501+
1502+
int i = 0, j = 0; // i 指向主串的当前起始位置, j 指向模式串的当前匹配位置
1503+
while (i <= haystack_len - needle_len) {
1504+
if (haystack[i + j] == needle[j]) {
1505+
j++;
1506+
if (j == needle_len) {
1507+
free(next);
1508+
next = NULL
1509+
return i;
1510+
}
1511+
} else {
1512+
i += j - next[j]; // 调整主串的起始位置
1513+
j = j > 0 ? next[j] : 0;
1514+
}
1515+
}
1516+
1517+
free(next);
1518+
next = NULL;
1519+
return -1;
1520+
}
1521+
```
1522+
14591523
<p align="center">
14601524
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
14611525
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>

‎problems/0037.解数独.md

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -366,40 +366,56 @@ class Solution:
366366
"""
367367
Do not return anything, modify board in-place instead.
368368
"""
369-
self.backtracking(board)
370-
371-
def backtracking(self, board: List[List[str]]) -> bool:
372-
# 若有解,返回True;若无解,返回False
373-
for i in range(len(board)): # 遍历行
374-
for j in range(len(board[0])): # 遍历列
375-
# 若空格内已有数字,跳过
376-
if board[i][j] != '.': continue
377-
for k in range(1, 10):
378-
if self.is_valid(i, j, k, board):
379-
board[i][j] = str(k)
380-
if self.backtracking(board): return True
381-
board[i][j] = '.'
382-
# 若数字1-9都不能成功填入空格,返回False无解
383-
return False
384-
return True # 有解
385-
386-
def is_valid(self, row: int, col: int, val: int, board: List[List[str]]) -> bool:
387-
# 判断同一行是否冲突
388-
for i in range(9):
389-
if board[row][i] == str(val):
390-
return False
391-
# 判断同一列是否冲突
392-
for j in range(9):
393-
if board[j][col] == str(val):
394-
return False
395-
# 判断同一九宫格是否有冲突
396-
start_row = (row // 3) * 3
397-
start_col = (col // 3) * 3
398-
for i in range(start_row, start_row + 3):
399-
for j in range(start_col, start_col + 3):
400-
if board[i][j] == str(val):
401-
return False
402-
return True
369+
row_used = [set() for _ in range(9)]
370+
col_used = [set() for _ in range(9)]
371+
box_used = [set() for _ in range(9)]
372+
for row in range(9):
373+
for col in range(9):
374+
num = board[row][col]
375+
if num == ".":
376+
continue
377+
row_used[row].add(num)
378+
col_used[col].add(num)
379+
box_used[(row // 3) * 3 + col // 3].add(num)
380+
self.backtracking(0, 0, board, row_used, col_used, box_used)
381+
382+
def backtracking(
383+
self,
384+
row: int,
385+
col: int,
386+
board: List[List[str]],
387+
row_used: List[List[int]],
388+
col_used: List[List[int]],
389+
box_used: List[List[int]],
390+
) -> bool:
391+
if row == 9:
392+
return True
393+
394+
next_row, next_col = (row, col + 1) if col < 8 else (row + 1, 0)
395+
if board[row][col] != ".":
396+
return self.backtracking(
397+
next_row, next_col, board, row_used, col_used, box_used
398+
)
399+
400+
for num in map(str, range(1, 10)):
401+
if (
402+
num not in row_used[row]
403+
and num not in col_used[col]
404+
and num not in box_used[(row // 3) * 3 + col // 3]
405+
):
406+
board[row][col] = num
407+
row_used[row].add(num)
408+
col_used[col].add(num)
409+
box_used[(row // 3) * 3 + col // 3].add(num)
410+
if self.backtracking(
411+
next_row, next_col, board, row_used, col_used, box_used
412+
):
413+
return True
414+
board[row][col] = "."
415+
row_used[row].remove(num)
416+
col_used[col].remove(num)
417+
box_used[(row // 3) * 3 + col // 3].remove(num)
418+
return False
403419
```
404420

405421
### Go

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /