Skip to content

Commit cc45eae

Browse files
committed
分割回文字符串
1 parent 5837fa5 commit cc45eae

File tree

1 file changed

+44
-60
lines changed

1 file changed

+44
-60
lines changed

basic_algorithm/dp.md

+44-60
Original file line numberDiff line numberDiff line change
@@ -283,31 +283,21 @@ bool canJump(vector<int>& nums) {
283283
> 数组中的每个元素代表你在该位置可以跳跃的最大长度。
284284
> 你的目标是使用最少的跳跃次数到达数组的最后一个位置。
285285
286-
```go
287-
func jump(nums []int) int {
288-
// 状态:f[i] 表示从起点到当前位置最小次数
289-
// 推导:f[i] = f[j],a[j]+j >=i,min(f[j]+1)
290-
// 初始化:f[0] = 0
291-
// 结果:f[n-1]
292-
f := make([]int, len(nums))
293-
f[0] = 0
294-
for i := 1; i < len(nums); i++ {
295-
// f[i] 最大值为i
296-
f[i] = i
297-
// 遍历之前结果取一个最小值+1
298-
for j := 0; j < i; j++ {
299-
if nums[j]+j >= i {
300-
f[i] = min(f[j]+1,f[i])
301-
}
286+
```c++
287+
int jump(vector<int>& nums) {
288+
int size = nums.size();
289+
vector<int> cache(size);
290+
cache[0] = 0;
291+
// cache[i + 1] >= cache[i]
292+
for (int i = 1, farest = 0; i < size; ++i) {
293+
while (farest < size && farest + nums[farest] < i) {
294+
++farest;
302295
}
296+
// 假设你总是可以到达数组的最后一个位置。
297+
// 可以认定farest + nums[farest]一定会大于i
298+
cache[i] = cache[farest] + 1;
303299
}
304-
return f[len(nums)-1]
305-
}
306-
func min(a, b int) int {
307-
if a > b {
308-
return b
309-
}
310-
return a
300+
return cache.back();
311301
}
312302
```
313303
@@ -316,43 +306,37 @@ func min(a, b int) int {
316306
> 给定一个字符串 _s_,将 _s_ 分割成一些子串,使每个子串都是回文串。
317307
> 返回符合要求的最少分割次数。
318308
319-
```go
320-
func minCut(s string) int {
321-
// state: f[i] "前i"个字符组成的子字符串需要最少几次cut(个数-1为索引)
322-
// function: f[i] = MIN{f[j]+1}, j < i && [j+1 ~ i]这一段是一个回文串
323-
// intialize: f[i] = i - 1 (f[0] = -1)
324-
// answer: f[s.length()]
325-
if len(s) == 0 || len(s) == 1 {
326-
return 0
327-
}
328-
f := make([]int, len(s)+1)
329-
f[0] = -1
330-
f[1] = 0
331-
for i := 1; i <= len(s); i++ {
332-
f[i] = i - 1
333-
for j := 0; j < i; j++ {
334-
if isPalindrome(s, j, i-1) {
335-
f[i] = min(f[i], f[j]+1)
336-
}
337-
}
338-
}
339-
return f[len(s)]
340-
}
341-
func min(a, b int) int {
342-
if a > b {
343-
return b
344-
}
345-
return a
346-
}
347-
func isPalindrome(s string, i, j int) bool {
348-
for i < j {
349-
if s[i] != s[j] {
350-
return false
351-
}
352-
i++
353-
j--
354-
}
355-
return true
309+
```c++
310+
int minCut(string s) {
311+
if (s.size() <= 1) {
312+
return 0;
313+
}
314+
auto size = s.size();
315+
vector<int> cache(size);
316+
for (int i = 0; i < size; ++i) {
317+
cache[i] = i;
318+
}
319+
vector<vector<bool>> isPalindrome(size, vector<bool>(size));
320+
for (int right = 0; right < size; ++right) {
321+
for (int left = 0; left <= right; ++left) {
322+
// 如果头尾相同,可能为回文!
323+
// len < 3时,直接判断为回文
324+
// len >= 3时,判断里面一层,左右往里缩一格
325+
isPalindrome[left][right] = s[right] == s[left] && (right - left < 3 || isPalindrome[left + 1][right - 1]);
326+
}
327+
}
328+
for (int i = 1; i < size; ++i) {
329+
if (isPalindrome[0][i]) {
330+
cache[i] = 0;
331+
continue;
332+
}
333+
for (int j = 0; j < i; ++j) {
334+
if (isPalindrome[j + 1][i]) {
335+
cache[i] = min(cache[j] + 1, cache[i]);
336+
}
337+
}
338+
}
339+
return cache.back();
356340
}
357341
```
358342

0 commit comments

Comments
 (0)