1. 程式人生 > >[LeetCode] Palindromic Substrings 迴文子字串

[LeetCode] Palindromic Substrings 迴文子字串

Given a string, your task is to count how many palindromic substrings in this string.

The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters.

Example 1:

Input: "abc"
Output: 3
Explanation: Three palindromic strings: "a", "b", "c".

Example 2:

Input: "aaa"
Output: 6
Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa".

Note:

  1. The input string length won't exceed 1000.

這道題給了我們一個字串,讓我們計算有多少個迴文子字串。博主看到這個題,下意識的想著應該是用DP來做,哼哼哧哧寫了半天,修修補補,終於通過了,但是博主寫的DP不是最簡便的方法,略顯複雜,這裡就不貼了。還是直接講解大神們的解法好了。其實這道題也可以用遞迴來做,而且思路非常的簡單粗暴。就是以字串中的每一個字元都當作迴文串中間的位置,然後向兩邊擴散,每當成功匹配兩個左右兩個字元,結果res自增1,然後再比較下一對。注意迴文字串有奇數和偶數兩種形式,如果是奇數長度,那麼i位置就是中間那個字元的位置,所以我們左右兩遍都從i開始遍歷;如果是偶數長度的,那麼i是最中間兩個字元的左邊那個,右邊那個就是i+1,這樣就能cover所有的情況啦,而且都是不同的迴文子字串,參見程式碼如下:

解法一:

class Solution {
public:
    int countSubstrings(string s) {
        if (s.empty()) return 0;
        int n = s.size(), res = 0;
        for (int i = 0; i < n; ++i) {
            helper(s, i, i, res);
            helper(s, i, i + 1, res);
        }
        return res;
    }
    
void helper(string s, int i, int j, int& res) { while (i >= 0 && j < s.size() && s[i] == s[j]) { --i; ++j; ++res; } } };

在剛開始的時候博主提到了自己寫的DP的方法比較複雜,為什麼呢,因為博主的dp[i][j]定義的是範圍[i, j]之間的子字串的個數,這樣我們其實還需要一個二維陣列來記錄子字串[i, j]是否是迴文串,那麼我們直接就將dp[i][j]定義成子字串[i, j]是否是迴文串就行了,然後我們i從n-1往0遍歷,j從i往n-1遍歷,然後我們看s[i]和s[j]是否相等,這時候我們需要留意一下,有了s[i]和s[j]相等這個條件後,i和j的位置關係很重要,如果i和j相等了,那麼dp[i][j]肯定是true;如果i和j是相鄰的,那麼dp[i][j]也是true;如果i和j中間只有一個字元,那麼dp[i][j]還是true;如果中間有多餘一個字元存在,那麼我們需要看dp[i+1][j-1]是否為true,若為true,那麼dp[i][j]就是true。賦值dp[i][j]後,如果其為true,結果res自增1,參見程式碼如下:

解法二:

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

類似題目:

參考資料: