@@ -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