欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

LeetCode:Palindrome Partitioning

系統 2112 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條評論
主站蜘蛛池模板: 久久精品一区二区三区四区 | 99久久精品国产导航 | 久久精品国产一区二区 | 国产片自拍 | 亚洲午夜精品视频 | 91精品观看 | 久久精品国产亚洲一区二区 | 国产欧美日韩精品一区二 | 久久精品中文字幕 | 夜色视频网 | 久久制服丝袜 | 午夜视频在线观看一区 | 97国产精品视频人人做人人爱 | 成人亚洲欧美日韩在线 | 国产日韩欧美一区二区 | 男人的天堂在线视频 | 亚洲国产精品久久 | 欧美一做特黄毛片 | 国产一级一级一级成人毛片 | 欧美日韩一区二区在线 | 午夜三级影院 | 成人毛片国产a | 国产精品久久久久久久久久免费 | 国产福利资源在线 | 日本一区二区不卡 | 亚洲精选一区 | 国产成人一区二区三区电影 | 日韩国产精品一区二区三区 | www.色.com| 亚洲 中文 欧美 日韩 在线观看 | 在线久草 | 精品在线一区二区 | 91精品久久 | 又黄又爽免费无遮挡在线观看 | 欧美激情 亚洲 | 一区二区三区在线 | 日本 | 麻豆精品国产自产在线 | 日日爽夜夜爽 | 日本三级一区二区 | 色天天爱天天狠天天透 | 狠狠干美女 |