题号 5
题目描述
给定一个字符串 s
,找到 s
中最长的回文子串。你可以假设 s
的最大长度为 1000。
示例1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例2:
输入: "cbbd"
输出: "bb"
解题思路1——暴力法
1- 找出给定字符串的所有子串
2- 按照子串的长度由大到小依次判断该子串是否是回文子串,如果找到一个回文子串,则该回文子串就是要找的最长的回文子串。
时间复杂度:O(n^3)
空间复杂度:O(1)
备注:显然这种解法太过于繁琐。
解题思路2——动态规划
Step1:描述问题的最优解结构特征
观察给定字符串s的某个子串 S( i, j ),其中 0<= i <= j <= s.length(),使用 P( i, j ) 记录子串 S( i, j ) 是否为回文子串,若是,则 P( i, j) 为1,否则为0。
1- 如果 j == i , 那么子串 S( i, i ) 只有一个字符,显然是回文子串,所以所有的 P( i , i ) = 1;
2- 如果 j == i+1,那么子串 S( i, i+1) 包含两个字符
(1)如果 S[ i ] == S[ i+1 ],则该子串为回文子串,令 P( i, i+1 ) = 1,并且如果该子串长度大于目前找到的回文子串的最大长度 maxLength ,则记录下该子串的始末位置以及该子串长度;
(2)如果 S[ i ] != S[ i+1 ],则该子串不是回文子串,令 P( i, i+1 ) =0即可。
3- 对于 j > i+1 的情况:
i | i + 1 | …… | j - 1 | j |
…… |
(1)如果 S( i+1, j-1 ) 是回文子串,即 P( i+1, j-1 ) == 1 时:
a. 如果 S[ i ] == S [ j ],则子串 S( i, j ) 为回文子串,令 P( i, j ) = 1,并且如果该子串长度大于目前找到的回文子串的最大长度 maxLength ,则记录下该子串的始末位置以及该子串长度;
b. 如果 S[ i ] != S[ j ],则子串 S( i, j ) 不是回文子串,令 P( i, j ) =0。
(2)如果 S( i+1, j-1 ) 不是回文子串,则显然 S( i, j ) 更加不是回文子串。
对于第三点需要注意的一点时,当我们对 三字符子串 进行判断是否为回文子串时,需要用到 两字符子串 是否是回文子串,因此必须按照子串的长度由小到大的顺序进行处理。
关系如下图所示:
简化来说,对于 j > i+1 的情况,P( i, j ) = P( i+1, j-1 ) ∩ ( S[ i ] == S[ j ] )