leetcode-5-最长回文子串
题解:
回文串:如果一个字符串正着读和反着读都是一样的那这个字符串就是回文串。
对于一个子串而言,如果它是回文串,并且长度大于 2,那么将它首尾的两个字母去除之后,它仍然是个回文串。
1、初始化字典dic_len={}记录回文子串及其长度。其key值代表回文子串的长度,value值代表回文子串;
2、初始化长度为n*n的二维数组dp用来表示子串是否是回文串;由于左边界一定小于或等于右边界,所以只需要对dp的上三角进行赋值。按照下图红色箭头方向进行赋值;
3、dp[i][j]==True代表左边界为i右边界为j的子串是回文串;dp[i][j]==False代表左边界为i右边界为j的子串不是回文串;
4、使用双层for循环对dp[i][j]赋值(其中j>=i);(具体赋值步骤见步骤8)
5、当s[i]!=s[j]时,则dp[i][j]不是回文串直接将dp[i][j]赋值为False;
6、当s[i]==s[j]时,分两种情况:
(1)当子串的长度小于等于3即j-i<3时,子串肯定是回文串则dp[i][j]==True;
(2)当子串的长度大于3时即j-i>=3时,子串是否为回文串取决于dp[i+1][j-1]即dp[i][j]=dp[i+1][j-1];
7、如果dp[i][j]==True,则更新dic_len的key值为j-i+1,对应的value值为s[i,j+1];
8、循环结束后返回dic_len的最大key对应的value。
9、根据步骤6中的第(2)种情况,所以按照图中箭头的方向依次对dp进行赋值即在j固定的情况下依次增大i且使i<==j对dp进行赋值。使用如下循环模板实现:
for j in range(n):
for i in range(j+1):
dp[i][j]="XXXXX"
下图:
dp[0][3]的计算逻辑:在s[0]!=s[3],dp[0][3]=False;
dp[0][4]的计算逻辑:在s[0]==s[4]时,子串长度大于3则dp[0][4]=dp[1][3];
dp[1][4]的计算逻辑:在s[1]!=s[4]时,dp[1][4]=False;
核心:使用动态规划解题,动态规划方程如下: