Skip to content

Commit a982d2d

Browse files
authored
Merge branch 'youngyangyang04:master' into master
2 parents 947424d + d22464f commit a982d2d

File tree

112 files changed

+2870
-4563
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+2870
-4563
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.idea/
2+
.DS_Store
3+
.vscode
4+
.temp
5+
.cache
6+
*.iml
7+
__pycache__

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@
106106
4. [数组:977.有序数组的平方](./problems/0977.有序数组的平方.md)
107107
5. [数组:209.长度最小的子数组](./problems/0209.长度最小的子数组.md)
108108
6. [数组:区间和](./problems/kamacoder/0058.区间和.md)
109-
6. [数组:59.螺旋矩阵II](./problems/0059.螺旋矩阵II.md)
110-
8. [数组:开发商购买土地](./problems/kamacoder/0044.开发商购买土地.md)
109+
7. [数组:开发商购买土地](./problems/kamacoder/0044.开发商购买土地.md)
110+
8. [数组:59.螺旋矩阵II](./problems/0059.螺旋矩阵II.md)
111111
9. [数组:总结篇](./problems/数组总结篇.md)
112112

113113
## 链表
@@ -196,7 +196,6 @@
196196
12. [二叉树:110.平衡二叉树](./problems/0110.平衡二叉树.md)
197197
13. [二叉树:257.二叉树的所有路径](./problems/0257.二叉树的所有路径.md)
198198
14. [本周总结!(二叉树)](./problems/周总结/20201003二叉树周末总结.md)
199-
15. [二叉树:二叉树中递归带着回溯](./problems/二叉树中递归带着回溯.md)
200199
16. [二叉树:404.左叶子之和](./problems/0404.左叶子之和.md)
201200
17. [二叉树:513.找树左下角的值](./problems/0513.找树左下角的值.md)
202201
18. [二叉树:112.路径总和](./problems/0112.路径总和.md)
@@ -400,7 +399,7 @@
400399
24. [图论:Bellman_ford 算法](./problems/kamacoder/0094.城市间货物运输I.md)
401400
25. [图论:Bellman_ford 队列优化算法(又名SPFA)](./problems/kamacoder/0094.城市间货物运输I-SPFA.md)
402401
26. [图论:Bellman_ford之判断负权回路](./problems/kamacoder/0095.城市间货物运输II.md)
403-
27. [图论:Bellman_ford之单源有限最短路](./problems/kamacoder/0095.城市间货物运输II.md)
402+
27. [图论:Bellman_ford之单源有限最短路](./problems/kamacoder/0096.城市间货物运输III.md)
404403
28. [图论:Floyd 算法](./problems/kamacoder/0097.小明逛公园.md)
405404
29. [图论:A * 算法](./problems/kamacoder/0126.骑士的攻击astar.md)
406405
30. [图论:最短路算法总结篇](./problems/kamacoder/最短路问题总结篇.md)

problems/0005.最长回文子串.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,60 @@ public:
256256
* 时间复杂度:O(n^2)
257257
* 空间复杂度:O(1)
258258

259+
### Manacher 算法
259260

261+
Manacher 算法的关键在于高效利用回文的对称性,通过插入分隔符和维护中心、边界等信息,在线性时间内找到最长回文子串。这种方法避免了重复计算,是处理回文问题的最优解。
262+
263+
```c++
264+
//Manacher 算法
265+
class Solution {
266+
public:
267+
string longestPalindrome(string s) {
268+
// 预处理字符串,在每个字符之间插入 '#'
269+
string t = "#";
270+
for (char c : s) {
271+
t += c; // 添加字符
272+
t += '#';// 添加分隔符
273+
}
274+
int n = t.size();// 新字符串的长度
275+
vector<int> p(n, 0);// p[i] 表示以 t[i] 为中心的回文半径
276+
int center = 0, right = 0;// 当前回文的中心和右边界
277+
278+
279+
// 遍历预处理后的字符串
280+
for (int i = 0; i < n; i++) {
281+
// 如果当前索引在右边界内,利用对称性初始化 p[i]
282+
if (i < right) {
283+
p[i] = min(right - i, p[2 * center - i]);
284+
}
285+
// 尝试扩展回文
286+
while (i - p[i] - 1 >= 0 && i + p[i] + 1 < n && t[i - p[i] - 1] == t[i + p[i] + 1]) {
287+
p[i]++;// 增加回文半径
288+
}
289+
// 如果当前回文扩展超出右边界,更新中心和右边界
290+
if (i + p[i] > right) {
291+
center = i;// 更新中心
292+
right = i + p[i];// 更新右边界
293+
}
294+
}
295+
// 找到最大回文半径和对应的中心
296+
int maxLen = 0, centerIndex = 0;
297+
for (int i = 0; i < n; i++) {
298+
if (p[i] > maxLen) {
299+
maxLen = p[i];// 更新最大回文长度
300+
centerIndex = i;// 更新中心索引
301+
}
302+
}
303+
// 计算原字符串中回文子串的起始位置并返回
304+
return s.substr((centerIndex - maxLen) / 2, maxLen);
305+
}
306+
};
307+
```
308+
309+
310+
311+
* 时间复杂度:O(n)
312+
* 空间复杂度:O(n)
260313

261314
## 其他语言版本
262315

@@ -682,3 +735,4 @@ public class Solution {
682735
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
683736
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
684737
</a>
738+

problems/0046.全排列.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ class Solution {
201201
public void backtrack(int[] nums, LinkedList<Integer> path) {
202202
if (path.size() == nums.length) {
203203
result.add(new ArrayList<>(path));
204+
return;
204205
}
205206
for (int i =0; i < nums.length; i++) {
206207
// 如果path中已有,则跳过
@@ -524,3 +525,4 @@ public class Solution
524525
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
525526
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
526527
</a>
528+

problems/0053.最大子序和.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ class Solution:
214214
return result
215215

216216
```
217+
贪心法
217218
```python
218219
class Solution:
219220
def maxSubArray(self, nums):
@@ -226,9 +227,55 @@ class Solution:
226227
if count <= 0: # 相当于重置最大子序起始位置,因为遇到负数一定是拉低总和
227228
count = 0
228229
return result
230+
```
231+
动态规划
232+
```python
233+
class Solution:
234+
def maxSubArray(self, nums: List[int]) -> int:
235+
dp = [0] * len(nums)
236+
dp[0] = nums[0]
237+
res = nums[0]
238+
for i in range(1, len(nums)):
239+
dp[i] = max(dp[i-1] + nums[i], nums[i])
240+
res = max(res, dp[i])
241+
return res
242+
```
243+
244+
动态规划
245+
246+
```python
247+
class Solution:
248+
def maxSubArray(self, nums):
249+
if not nums:
250+
return 0
251+
dp = [0] * len(nums) # dp[i]表示包括i之前的最大连续子序列和
252+
dp[0] = nums[0]
253+
result = dp[0]
254+
for i in range(1, len(nums)):
255+
dp[i] = max(dp[i-1]+nums[i], nums[i]) # 状态转移公式
256+
if dp[i] > result:
257+
result = dp[i] # result 保存dp[i]的最大值
258+
return result
259+
```
260+
261+
动态规划优化
229262

263+
```python
264+
class Solution:
265+
def maxSubArray(self, nums: List[int]) -> int:
266+
max_sum = float("-inf") # 初始化结果为负无穷大,方便比较取最大值
267+
current_sum = 0 # 初始化当前连续和
268+
269+
for num in nums:
230270

271+
# 更新当前连续和
272+
# 如果原本的连续和加上当前数字之后没有当前数字大,说明原本的连续和是负数,那么就直接从当前数字开始重新计算连续和
273+
current_sum = max(current_sum+num, num)
274+
max_sum = max(max_sum, current_sum) # 更新结果
275+
276+
return max_sum
231277
```
278+
232279
### Go
233280
贪心法
234281
```go

problems/0055.跳跃游戏.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,23 @@ class Solution:
143143
return False
144144
```
145145

146+
```python
147+
## 基于当前最远可到达位置判断
148+
class Solution:
149+
def canJump(self, nums: List[int]) -> bool:
150+
far = nums[0]
151+
for i in range(len(nums)):
152+
# 要考虑两个情况
153+
# 1. i <= far - 表示 当前位置i 可以到达
154+
# 2. i > far - 表示 当前位置i 无法到达
155+
if i > far:
156+
return False
157+
far = max(far, nums[i]+i)
158+
# 如果循环正常结束,表示最后一个位置也可以到达,否则会在中途直接退出
159+
# 关键点在于,要想明白其实列表中的每个位置都是需要验证能否到达的
160+
return True
161+
```
162+
146163
### Go
147164

148165
```go

problems/0070.爬楼梯完全背包版本.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,16 @@ if __name__ == '__main__':
184184

185185
### Go:
186186
```go
187+
package main
188+
189+
import (
190+
"bufio"
191+
"fmt"
192+
"os"
193+
"strconv"
194+
"strings"
195+
)
196+
187197
func climbStairs(n int, m int) int {
188198
dp := make([]int, n+1)
189199
dp[0] = 1

problems/0093.复原IP地址.md

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,8 @@ class Solution {
376376
// 剪枝:ip段的长度最大是3,并且ip段处于[0,255]
377377
for (int i = start; i < s.length() && i - start < 3 && Integer.parseInt(s.substring(start, i + 1)) >= 0
378378
&& Integer.parseInt(s.substring(start, i + 1)) <= 255; i++) {
379-
// 如果ip段的长度大于1,并且第一位为0的话,continue
380379
if (i + 1 - start > 1 && s.charAt(start) - '0' == 0) {
381-
continue;
380+
break;
382381
}
383382
stringBuilder.append(s.substring(start, i + 1));
384383
// 当stringBuilder里的网段数量小于3时,才会加点;如果等于3,说明已经有3段了,最后一段不需要再加点
@@ -467,9 +466,37 @@ class Solution:
467466
num = int(s[start:end+1])
468467
return 0 <= num <= 255
469468

469+
回溯(版本三)
470470

471-
472-
471+
```python
472+
class Solution:
473+
def restoreIpAddresses(self, s: str) -> List[str]:
474+
result = []
475+
self.backtracking(s, 0, [], result)
476+
return result
477+
478+
def backtracking(self, s, startIndex, path, result):
479+
if startIndex == len(s):
480+
result.append('.'.join(path[:]))
481+
return
482+
483+
for i in range(startIndex, min(startIndex+3, len(s))):
484+
# 如果 i 往后遍历了,并且当前地址的第一个元素是 0 ,就直接退出
485+
if i > startIndex and s[startIndex] == '0':
486+
break
487+
# 比如 s 长度为 5,当前遍历到 i = 3 这个元素
488+
# 因为还没有执行任何操作,所以此时剩下的元素数量就是 5 - 3 = 2 ,即包括当前的 i 本身
489+
# path 里面是当前包含的子串,所以有几个元素就表示储存了几个地址
490+
# 所以 (4 - len(path)) * 3 表示当前路径至多能存放的元素个数
491+
# 4 - len(path) 表示至少要存放的元素个数
492+
if (4 - len(path)) * 3 < len(s) - i or 4 - len(path) > len(s) - i:
493+
break
494+
if i - startIndex == 2:
495+
if not int(s[startIndex:i+1]) <= 255:
496+
break
497+
path.append(s[startIndex:i+1])
498+
self.backtracking(s, i+1, path, result)
499+
path.pop()
473500
```
474501

475502
### Go

problems/0110.平衡二叉树.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -609,10 +609,13 @@ class Solution:
609609
while stack:
610610
node = stack.pop()
611611
if node:
612-
stack.append(node)
612+
stack.append(node) #
613613
stack.append(None)
614-
if node.left: stack.append(node.left)
615-
if node.right: stack.append(node.right)
614+
# 采用数组进行迭代,先将右节点加入,保证左节点能够先出栈
615+
if node.right: #
616+
stack.append(node.right)
617+
if node.left: #
618+
stack.append(node.left)
616619
else:
617620
real_node = stack.pop()
618621
left, right = height_map.get(real_node.left, 0), height_map.get(real_node.right, 0)

problems/0112.路径总和.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -564,10 +564,10 @@ class Solution:
564564

565565
return False
566566

567-
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
567+
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
568568
if root is None:
569569
return False
570-
return self.traversal(root, sum - root.val)
570+
return self.traversal(root, targetSum - root.val)
571571
```
572572

573573
(版本二) 递归 + 精简
@@ -579,12 +579,12 @@ class Solution:
579579
# self.left = left
580580
# self.right = right
581581
class Solution:
582-
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
582+
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
583583
if not root:
584584
return False
585-
if not root.left and not root.right and sum == root.val:
585+
if not root.left and not root.right and targetSum == root.val:
586586
return True
587-
return self.hasPathSum(root.left, sum - root.val) or self.hasPathSum(root.right, sum - root.val)
587+
return self.hasPathSum(root.left, targetSum - root.val) or self.hasPathSum(root.right, targetSum - root.val)
588588

589589
```
590590
(版本三) 迭代
@@ -596,7 +596,7 @@ class Solution:
596596
# self.left = left
597597
# self.right = right
598598
class Solution:
599-
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
599+
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
600600
if not root:
601601
return False
602602
# 此时栈里要放的是pair<节点指针,路径数值>
@@ -659,13 +659,13 @@ class Solution:
659659

660660
return
661661

662-
def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
662+
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
663663
self.result.clear()
664664
self.path.clear()
665665
if not root:
666666
return self.result
667667
self.path.append(root.val) # 把根节点放进路径
668-
self.traversal(root, sum - root.val)
668+
self.traversal(root, targetSum - root.val)
669669
return self.result
670670
```
671671

@@ -678,7 +678,7 @@ class Solution:
678678
# self.left = left
679679
# self.right = right
680680
class Solution:
681-
def pathSum(self, root: TreeNode, targetSum: int) -> List[List[int]]:
681+
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
682682

683683
result = []
684684
self.traversal(root, targetSum, [], result)
@@ -703,7 +703,7 @@ class Solution:
703703
# self.left = left
704704
# self.right = right
705705
class Solution:
706-
def pathSum(self, root: TreeNode, targetSum: int) -> List[List[int]]:
706+
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
707707
if not root:
708708
return []
709709
stack = [(root, [root.val])]

0 commit comments

Comments
 (0)