647. 回文子串(C++)


 題目描述:

給定一個字符串,你的任務是計算這個字符串中有多少個回文子串。

具有不同開始位置或結束位置的子串,即使是由相同的字符組成,也會被計為是不同的子串。

示例 1:

輸入: "abc"
輸出: 3
解釋: 三個回文子串: "a", "b", "c".
示例 2:

輸入: "aaa"
輸出: 6
說明: 6個回文子串: "a", "a", "a", "aa", "aa", "aaa".
注意:

輸入的字符串長度不會超過1000。

思想1:動態規划

狀態:dp[i][j] 表示字符串s在[i,j]區間的子串是否是一個回文串。
狀態轉移方程:當 s[i] == s[j] && (j - i < 2 || dp[i + 1][j - 1]) 時,dp[i][j]=true,否則為false
狀態轉移方程的含義:

  • 當只有一個字符時,比如a自然是一個回文串。
  • 當有兩個字符時,如果是相等的,比如aa,也是一個回文串。
  • 當有三個及以上字符時,比如ababa這個字符記作串1,把兩邊的a去掉,也就是bab記作串2,可以看出只要串2是一個回文串,那么左右各多了一個a的串1必定也是回文串。所以當s[i]==s[j]時,自然要看dp[i+1][j-1]是不是一個回文串。

 

代碼1:

class Solution {
public:
    int countSubstrings(string s) {
        int len = s.size();
        int count = 0;
        vector<vector<bool> >dp(len,vector<bool>(len));
        for(int i=0;i<len;i++){
            for(int j=0;j<=i;j++){
                if(s[i]==s[j]&&(i-j<2||dp[j+1][i-1])){
                    dp[j][i] = true;
                    count++;
                }
            }
        }
        return count;
    }
};

 

思想2:中心擴展法

對一個字符串ababa,選擇最中間的a作為中心點,往兩邊擴散,第一次擴散發現left指向的是b,right指向的也是b,所以是回文串,繼續擴散,同理ababa也是回文串。

這個是確定了一個中心點后的尋找的路徑,只要尋找到所有的中心點,問題就解決了。

中心點一共有多少個呢?看起來像是和字符串長度相等,但會發現,如果是這樣,上面的例子永遠也搜不到abab,想象一下單個字符的哪個中心點擴展可以得到這個子串?似乎不可能。所以中心點不能只有單個字符構成,還要包括兩個字符,比如上面這個子串abab,就可以有中心點ba擴展一次得到,所以最終的中心點由2 * len - 1個,分別是len個單字符和len - 1個雙字符。

如果上面看不太懂的話,還可以看看下面幾個問題:

為什么有 2 * len - 1 個中心點?

  • aba 有5個中心點,分別是 a、b、c、ab、ba
  • abba 有7個中心點,分別是 a、b、b、a、ab、bb、ba

什么是中心點?

  • 中心點即left指針和right指針初始化指向的地方,可能是一個也可能是兩個

為什么不可能是三個或者更多?

  • 因為3個可以由1個擴展一次得到,4個可以由兩個擴展一次得到

代碼2:

class Solution {
public:
    int countSubstrings(string s) {
        int count = 0;
        int len = s.size();
        for(int center=0;center<2 * len -1;center++){
            //left和right指針和中心點的關系是:left有一個很明顯的2倍關系的存在,其次是right,
       //可能和left指向同一個(偶數時),也可能往后移動一個(奇數)
int left = center / 2; int right = left + center % 2; while(left>=0 && right<len && s[left]==s[right]){ count++; left--; right++; } } return count; } };

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM