LeetCode 647 回文子串_子串

题目链接: 力扣

思路:动态规划

dp[i][j]表示s下标[i:j]的子串是否是回文串,问题转化为只要遍历dp数组,统计true的个数

确定边界情况:

●当i=j时,dp[i][i]表示s下标i到i的子串,只有一个字符,一定是回文子串,所以i=j时,dp[i][i]为True

●当j-i+1=2时,dp[i][j]表示s下标从i到i+1子串,只有两个字符,如果两个字符相等,是回文串

状态转移方程:

●当s【i】=s【j】,且dp【i+1】【j-1】为真,dp【i】【j】是回文

LeetCode 647 回文子串_i++_02

 ●其他情况,dp【i】【j】不是回文

LeetCode 647 回文子串_回文串_03

 

注意遍历顺序

LeetCode 647 回文子串_子串_04

 

for (int i=s.size()-3; i>=0; i--)
            for (int j =i+2; j<=s.size(); j++)
  • 1.
  • 2.

代码:

class Solution {
public:
    int countSubstrings(string s) {
        if (s.size() == 1)
        {
            return 1;
        }
        vector<vector<bool>>dp(s.size(), vector<bool>(s.size(), false));

        for (int i = 0; i < s.size(); i++)
        {
            dp[i][i] = true;
        }
        for (int i = 0; i < s.size() - 1; i++)
        {
            if (s[i] == s[i + 1])
                dp[i][i + 1] = true;
        }
        for (int i=s.size()-3; i>=0; i--)
        {
            for (int j =i+2; j<=s.size(); j++)
            {
                if (s[i] == s[j] && dp[i + 1][j - 1])
                {
                    dp[i][j] = true;
                }

            }
        }
        int result = 0;
        for (int i = 0; i < s.size(); i++)
        {
            for (int j = i; j < s.size(); j++)
            {
                if (dp[i][j] == true)
                {
                    result++;
                }
            }
        }
        return result;
    }
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.