亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

LeetCode:Palindrome Partitioning

系統 2027 0

LeetCode:Palindrome Partitioning

題目如下:(把一個字符串劃分成幾個回文子串,枚舉所有可能的劃分)

Given a string? s , partition? s ?such that every substring of the partition is a palindrome.

Return all possible palindrome partitioning of? s .

For example, given? s ?=? "aab" ,
Return

[ ["aa","b"], ["a","a","b"] ]

?

分析 :首先對字符串的所有子串判斷是否是回文,設f[i][j] = true表示以i為起點,長度為j的子串是回文,等于false表示不是回文,那么求f[i][j]的動態規劃方程如下:

  • 當j = 1,f[i][j] = true;

  • 當j = 2,f[i][j] = (s[i]==s[i+1]),其中s是輸入字符串

  • 當j > 2, f[i][j] = f[i+1][j-2] && (s[i] == s[i+j-1])(即判斷s[m..n]是否是回文時:只要s[m+1...n-1]是回文并且s[m] = s[n],那么它就是回文,否則不是回文)

這一題也可以不用動態規劃來求f,可以用普通的判斷回文的方式判斷每個子串是否為回文。 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? 本文地址

求得f后,根據 f 可以構建一棵樹,可以通過DFS來枚舉所有的分割方式,代碼如下:

        
           1
        
        
          class
        
        
           Solution {


        
        
           2
        
        
          public
        
        
          :


        
        
           3
        
             vector<vector<
        
          string
        
        >> partition(
        
          string
        
        
           s) {


        
        
           4
        
        
          //
        
        
           IMPORTANT: Please reset any member data you declared, as


        
        
           5
        
        
          //
        
        
           the same Solution instance will be reused for each test case.
        
        
           6
        
                 vector< vector<
        
          string
        
        > >
        
          res;


        
        
           7
        
        
          int
        
         len =
        
           s.length();


        
        
           8
        
        
          if
        
        (len == 
        
          0
        
        )
        
          return
        
        
           res;


        
        
           9
        
        
          //
        
        
          f[i][j] = true表示以i為起點,長度為j的子串是回文
        
        
          10
        
        
          bool
        
         **f = 
        
          new
        
        
          bool
        
        *
        
          [len];


        
        
          11
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
         ; i < len; i++
        
          )


        
        
          12
        
        
                  {


        
        
          13
        
                     f[i] = 
        
          new
        
        
          bool
        
        [len+
        
          1
        
        
          ];


        
        
          14
        
        
          for
        
        (
        
          int
        
         j = 
        
          0
        
        ; j < len+
        
          1
        
        ; j++
        
          )


        
        
          15
        
                         f[i][j] = 
        
          0
        
        
          ;


        
        
          16
        
                     f[i][
        
          1
        
        ] = 
        
          true
        
        
          ;


        
        
          17
        
        
                  }


        
        
          18
        
        
          for
        
        (
        
          int
        
         k = 
        
          2
        
        ; k <= len; k++
        
          )


        
        
          19
        
        
                  {


        
        
          20
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
        ; i <= len-k; i++
        
          )


        
        
          21
        
        
                      {


        
        
          22
        
        
          if
        
        (k == 
        
          2
        
        )f[i][
        
          2
        
        ] = (s[i] == s[i+
        
          1
        
        
          ]);


        
        
          23
        
        
          else
        
         f[i][k] = f[i+
        
          1
        
        ][k-
        
          2
        
        ] && (s[i] == s[i+k-
        
          1
        
        
          ]);


        
        
          24
        
        
                      }


        
        
          25
        
        
                  }


        
        
          26
        
                 vector<
        
          string
        
        >
        
           tmp;


        
        
          27
        
                 DFSRecur(s, f, 
        
          0
        
        
          , res, tmp);


        
        
          28
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
         ; i < len; i++
        
          )


        
        
          29
        
        
                      delete [](f[i]);


        
        
          30
        
        
                  delete []f;


        
        
          31
        
        
          return
        
        
           res;


        
        
          32
        
        
              }


        
        
          33
        
        
          34
        
        
          void
        
         DFSRecur(
        
          const
        
        
          string
        
         &s, 
        
          bool
        
         **f, 
        
          int
        
        
           i, 


        
        
          35
        
                     vector< vector<
        
          string
        
        > > &res, vector<
        
          string
        
        > &
        
          tmp)


        
        
          36
        
             {
        
          //
        
        
          i為遍歷的起點
        
        
          37
        
        
          int
        
         len =
        
           s.length();


        
        
          38
        
        
          if
        
        (i >= len){res.push_back(tmp); 
        
          return
        
        
          ;}


        
        
          39
        
        
          for
        
        (
        
          int
        
         k = 
        
          1
        
        ; k <= len - i; k++
        
          )


        
        
          40
        
        
          if
        
        (f[i][k] == 
        
          true
        
        
          )


        
        
          41
        
        
                      {


        
        
          42
        
        
                          tmp.push_back(s.substr(i, k));


        
        
          43
        
                         DFSRecur(s, f, i+
        
          k, res, tmp);


        
        
          44
        
        
                          tmp.pop_back();


        
        
          45
        
        
                      }


        
        
          46
        
        
          47
        
        
              }


        
        
          48
        
         };
      

LeetCdoe:Palindrome Partitioning II

題目如下:(在上一題的基礎上,找出最小劃分次數)

Given a string? s , partition? s ?such that every substring of the partition is a palindrome.

Return the minimum cuts needed for a palindrome partitioning of? s .

For example, given? s ?=? "aab" ,
Return? 1 ?since the palindrome partitioning? ["aa","b"] ?could be produced using 1 cut. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 本文地址

算法1 :在上一題的基礎上,我們很容易想到的是在DFS時,求得樹的最小深度即可(遍歷時可以根據當前求得的深度進行剪枝),但是可能是遞歸層數太多,大數據時運行超時,也貼上代碼:

? View Code

算法2 :設f[i][j]是i為起點,長度為j的子串的最小分割次數,f[i][j] = 0時,該子串是回文,f的動態規劃方程是:

f[i][j] = min{f[i][k] + f[i+k][j-k] +1} ,其中 1<= k <j

這里f充當了兩個角色,一是記錄子串是否是回文,二是記錄子串的最小分割次數,可以結合上一題的動態規劃方程,算法復雜度是O(n^3), 還是大數據超時,代碼如下:

? View Code

算法3 :同上一題,用f來記錄子串是否是回文,另外優化最小分割次數的動態規劃方程如下,mins[i] 表示子串s[0...i]的最小分割次數:

  • 如果s[0...i]是回文,mins[i] = 0
  • 如果s[0...i]不是回文,mins[i] = min{mins[k] +1 (s[k+1...i]是回文) ?或 ?mins[k] + i-k ?(s[k+1...i]不是回文)} ,其中0<= k < i

代碼如下,大數據順利通過,結果Accept: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? 本文地址

        
           1
        
        
          class
        
        
           Solution {


        
        
           2
        
        
          public
        
        
          :


        
        
           3
        
        
          int
        
         minCut(
        
          string
        
        
           s) {


        
        
           4
        
        
          //
        
        
           IMPORTANT: Please reset any member data you declared, as


        
        
           5
        
        
          //
        
        
           the same Solution instance will be reused for each test case.
        
        
           6
        
        
          int
        
         len =
        
           s.length();


        
        
           7
        
        
          if
        
        (len <= 
        
          1
        
        )
        
          return
        
        
          0
        
        
          ;


        
        
           8
        
        
          //
        
        
          f[i][j] = true表示以i為起點,長度為j的子串是回文
        
        
           9
        
        
          bool
        
         **f = 
        
          new
        
        
          bool
        
        *
        
          [len];


        
        
          10
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
         ; i < len; i++
        
          )


        
        
          11
        
        
                  {


        
        
          12
        
                     f[i] = 
        
          new
        
        
          bool
        
        [len+
        
          1
        
        
          ];


        
        
          13
        
        
          for
        
        (
        
          int
        
         j = 
        
          0
        
        ; j < len+
        
          1
        
        ; j++
        
          )


        
        
          14
        
                         f[i][j] = 
        
          false
        
        
          ;


        
        
          15
        
                     f[i][
        
          1
        
        ] = 
        
          true
        
        
          ;


        
        
          16
        
        
                  }


        
        
          17
        
        
          int
        
         mins[len];
        
          //
        
        
          mins[i]表示s[0...i]的最小分割次數
        
        
          18
        
                 mins[
        
          0
        
        ] = 
        
          0
        
        
          ;


        
        
          19
        
        
          for
        
        (
        
          int
        
         k = 
        
          2
        
        ; k <= len; k++
        
          )


        
        
          20
        
        
                  {


        
        
          21
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
        ; i <= len-k; i++
        
          )


        
        
          22
        
        
                      {


        
        
          23
        
        
          if
        
        (k == 
        
          2
        
        )f[i][
        
          2
        
        ] = (s[i] == s[i+
        
          1
        
        
          ]);


        
        
          24
        
        
          else
        
         f[i][k] = f[i+
        
          1
        
        ][k-
        
          2
        
        ] && (s[i] == s[i+k-
        
          1
        
        
          ]);


        
        
          25
        
        
                      }


        
        
          26
        
        
          if
        
        (f[
        
          0
        
        ][k] == 
        
          true
        
        ){mins[k-
        
          1
        
        ] = 
        
          0
        
        ; 
        
          continue
        
        
          ;}


        
        
          27
        
                     mins[k-
        
          1
        
        ] = len - 
        
          1
        
        
          ;


        
        
          28
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
        ; i < k-
        
          1
        
        ; i++
        
          )


        
        
          29
        
        
                      {


        
        
          30
        
        
          int
        
        
           tmp;


        
        
          31
        
        
          if
        
        (f[i+
        
          1
        
        ][k-i-
        
          1
        
        ] == 
        
          true
        
        )tmp = mins[i]+
        
          1
        
        
          ;


        
        
          32
        
        
          else
        
         tmp = mins[i]+k-i-
        
          1
        
        
          ;


        
        
          33
        
        
          if
        
        (mins[k-
        
          1
        
        ] > tmp)mins[k-
        
          1
        
        ] =
        
           tmp;


        
        
          34
        
        
                      }


        
        
          35
        
        
                  }


        
        
          36
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
         ; i < len; i++
        
          )


        
        
          37
        
        
                      delete [](f[i]);


        
        
          38
        
        
                  delete []f;


        
        
          39
        
        
          return
        
         mins[len-
        
          1
        
        
          ];


        
        
          40
        
        
              }


        
        
          41
        
        
          42
        
         };
      

?【版權聲明】轉載請注明出處: http://www.cnblogs.com/TenosDoIt/p/3421283.html

?
?

LeetCode:Palindrome Partitioning


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产综合色在线视频区色吧图片 | 女性一级全黄生活片在线播放 | 亚洲swag精品自拍一区 | 草久免费视频 | 免费99热在线观看 | 欧美日韩国产另类一区二区三区 | 国产在热线精品视频国产一二 | 中文字幕在线观看免费 | 一级午夜视频 | 男人影院免费 | 四虎欧美 | 99久久99久久久精品齐齐鬼色 | 九九九色视频在线观看免费 | 久久综合噜噜激激的五月天 | 一级黄网 | 日韩中文字幕精品免费一区 | 国产毛片一区二区三区精品 | 国产欧美日韩一区二区三区视频 | 久久久www免费看片 久久久不卡 | 全免费午夜一级毛片真人 | 99色这里只有精品 | 婷婷爱爱| 国产福利一区二区精品视频 | 久久免费看 | 亚洲精品福利一区二区三区 | 国产欧美精品一区二区三区四区 | 日韩女人做爰大片 | 99久久99热久久精品免费 | 天天透天天操 | 国产综合婷婷 | 亚洲欧美一区二区三区在饯 | 青青青国产深夜福利视频 | 四虎永久免费网站免费观看 | 欧美精品亚洲一区二区在线播放 | 黄色在线免费观看网站 | 99这里有精品视频 | 青青操精品| 91久久国产精品视频 | 伊人网站 | 免费一级毛片在播放视频 | 羞羞视频在线看 |