@@ -283,31 +283,21 @@ bool canJump(vector<int>& nums) {
283
283
> 数组中的每个元素代表你在该位置可以跳跃的最大长度。
284
284
> 你的目标是使用最少的跳跃次数到达数组的最后一个位置。
285
285
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;
302
295
}
296
+ // 假设你总是可以到达数组的最后一个位置。
297
+ // 可以认定farest + nums[ farest] 一定会大于i
298
+ cache[ i] = cache[ farest] + 1;
303
299
}
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();
311
301
}
312
302
```
313
303
@@ -316,43 +306,37 @@ func min(a, b int) int {
316
306
> 给定一个字符串 _s_,将 _s_ 分割成一些子串,使每个子串都是回文串。
317
307
> 返回符合要求的最少分割次数。
318
308
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();
356
340
}
357
341
```
358
342
0 commit comments