5. Longest Palindromic Substring【medium】

解题思路

暴力解法 O(N^3):

字符串有 n(n-1)/2 个子串,对每个子串进行检测,看其是否是回文子串。因此复杂度为 O(N^3)。

从字符串中间开始扩展 O(N^2):

把字符串的每个点分别当成回文子串的中间点,开始往两端扩展,不断检测,直到两端不相等为止。因此复杂度为 O(N^2)。

动态规划 O(N^2):

用 dp[i][j] 表示下标为 i 开头 j 结尾的子串是否是回文子串。

转移方程:dp[i][j] = (dp[i + 1][j - 1] && s[i] == s[j]) 【含义:当且仅当子串首尾两端相等,且去除首尾两端依旧是回文串时,该子串才会是回文串】

初始条件:对于每个长度为1的子串 dp[i][i] 都为回文串;对于每个长度为2的子串 dp[i][i + 1],当其首尾两端相等时,其为回文串,否则不是。

实现代码:

// 5. Longest Palindromic Substring (动态规划)
string longestPalindrome(string s) {
  int length = s.size();
  if (length == 0) return s;
  int resI = 0, resJ = 0;
  bool dp[length + 1][length + 1];
  for (int i = 0; i <= length; i++)
    dp[i][i] = true;
  for (int i = 0; i < length; i++) {
    if (s[i] == s[i + 1]) {
      dp[i][i + 1] = true;
      if (resJ - resI < 1) {
        resI = i;
        resJ = i + 1;
      }
    } else {
      dp[i][i + 1] = false;
    }
  }
  for (int gap = 2; gap < length; gap++) {
    for (int i = 0; i + gap < length; i++) {
      int j = i + gap;
      if (s[i] == s[j] && dp[i + 1][j - 1]) {
        dp[i][j] = true;
        if (resJ - resI < j - i) {
          resI = i;
          resJ = j;
        }
      } else {
        dp[i][j] = false;
      }
    }
  }
  return s.substr(resI, resJ - resI + 1);
}

问题描述:

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example 1:

Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.

Example 2:

Input: "cbbd"
Output: "bb"

results matching ""

    No results matching ""