[M]Longest Palindromic Substring最长回文子串
题目描述
Given a string s, return the longest palindromic substring in s.
题解思路
动态规划——状态如何转移
一个回文去掉两头以后,剩下的部分依然是回文
- 如果一个字符串的头尾不相等,那么这个字符串一定不是回文串;如果一个字符串的头尾两字符相等,才继续判断下去。
- 如果里面的子串是回文,整体是回文串;如果子串不是回文串,整体就不是回文串。
即需要判断原字符串的一个子串是否为回文子串。
1.定义
dp[i][j] 的 True,False表示子串 s[i…j] 是否为回文子串
2.需要满足状态转移方程
dp[i][j] = (s[i] == s[j]) and dp[i + 1][j - 1]
3.说明
构成子串,因此 i 和 j 的关系是 i <= j
对 dp[i + 1][j - 1] 考虑边界情况:
边界条件是: [i + 1, j - 1] 不构成区间,即长度小于 2,即 j - 1 - (i + 1) + 1 < 2 ,即 j - i < 3。
j - i < 3 ,则区间长度 j - i + 1 < 4,即当子串 s[i…j] 的长度等于 2 或者等于 3 的时候,其实只需要判断一下头尾两个字符是否相等就可以直接下结论了。
- 如果子串 s[i + 1…j - 1] 只有 1 个字符,即去掉两头,剩下中间部分只有 11 个字符,显然是回文;
- 如果子串 s[i + 1…j - 1] 为空串,那么子串 s[i, j] 一定是回文子串。
因此在 s[i] == s[j] 和 j - i < 3 的前提下,直接得dp[i][j] = true,不满足上述条件才执行状态转移。
参考思路from这里的题解
4.初始化和输出什么
(可省略)初始化:单个字符一定是回文串,因此把对角线先初始化为 true,即 dp[i][i] = true 。
输出:只要一得到 dp[i][j] = true,就记录子串的长度和起始位置,没有必要截取消耗性能,记录此时的回文子串的「起始位置start」和「回文长度max_length」即可。
python代码
class Solution:
def longestPalindrome(self, s: str) -> str:
length=len(s)
dp=[[False]*length for _ in range(length)]
start=0
max_length=1
for i in range(length):
dp[i][i]=True
if length<2:
return s
for j in range(1,length):
for i in range(0,j):
if s[i]==s[j]:
if j-i<3:
dp[i][j]=True
else:
dp[i][j]=dp[i+1][j-1]
else:
dp[i][j]=False
if dp[i][j]:
cur_length=j-i+1
if cur_length>max_length:
max_length=cur_length
start=i
return s[start:start+max_length]
复杂度
时间复杂度:
O
(
N
2
)
O(N^2)
O(N2)
空间复杂度:
O
(
N
2
)
O(N^2)
O(N2)
—2020/10/16太弱以至于理解费劲优化无能QAQ----