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 57cec75

Browse files
Merge branch 'youngyangyang04:master' into master
2 parents a4f9f01 + 90fece3 commit 57cec75

File tree

50 files changed

+1884
-127
lines changed

Some content is hidden

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

50 files changed

+1884
-127
lines changed

‎.DS_Store

-6 KB
Binary file not shown.

‎.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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@
400400
24. [图论:Bellman_ford 算法](./problems/kamacoder/0094.城市间货物运输I.md)
401401
25. [图论:Bellman_ford 队列优化算法(又名SPFA)](./problems/kamacoder/0094.城市间货物运输I-SPFA.md)
402402
26. [图论:Bellman_ford之判断负权回路](./problems/kamacoder/0095.城市间货物运输II.md)
403-
27. [图论:Bellman_ford之单源有限最短路](./problems/kamacoder/0095.城市间货物运输II.md)
403+
27. [图论:Bellman_ford之单源有限最短路](./problems/kamacoder/0096.城市间货物运输III.md)
404404
28. [图论:Floyd 算法](./problems/kamacoder/0097.小明逛公园.md)
405405
29. [图论:A * 算法](./problems/kamacoder/0126.骑士的攻击astar.md)
406406
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: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,9 +467,37 @@ class Solution:
467467
num = int(s[start:end+1])
468468
return 0 <= num <= 255
469469

470+
回溯(版本三)
470471

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

475503
### 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)

0 commit comments

Comments
(0)

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