题目:最长回文子串
Category Difficulty Likes Dislikes algorithms Medium (31.73%) 2630 - Tags string | dynamic-programming Companies 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 示例 1: 输入: "babad" 输出: "bab" 注意: "aba" 也是一个有效答案。 示例 2: 输入: "cbbd" 输出: "bb"复杂度分析:
时间复杂度:O(N^3),这里 N 是字符串的长度,枚举字符串的左边界、右边界,然后继续验证子串是否是回文子串,这三种操作都与 N 相关;空间复杂度:O(1),只使用到常数个临时变量,与字符串长度无关。
首先第一步,我们需要定义dp数组的含义,定义二维布尔数组dp[i][j]dp[i][j]数组表示:
字符串s[i⋯j]是否为回文子串,如果是,dp[i][j] = true,如果不是,dp[i][j] = false。
如果我们现在已经知道了dp[i+1][j-1]了,那我们如何计算dp[i][j]呢?通过观察,我们发现:
如果s[i] == s[j]那么说明只要dp[i+1][j-1]是回文子串,那么是dp[i][j]也就是回文子串如果s[i] !=s [j]那么说明dp[i][j]必定不是回文子串。 if(s.charAt(i) == s.charAt(j)){ dp[i][j] = dp[i+1][j-1] }else{ dp[i][j] = false; }接下来我们需要考虑base case,这里显而易见,当只有一个字母的时候肯定是回文子串,所以初始化的dp表应该如下图所示。
for(int i = s.length()-1; i>=0; i--){ for(int j = i+1; j<s.length(); j++){ if(s.charAt(i) == s.charAt(j)){ dp[i][j] = dp[i+1][j-1] } else{ dp[i][j] = false; } } }这样就基本完成了这道题目。但是这样会有一种情况通过不了例如给的例子中的“cbbd”
这道题中的回文子串应该为**“bb”**但是我们的dp表中并没有计算出来,这是因为当计算dp[i][j]的时候,中间已经没有dp[i+1][j-1]了,这是我们在base case中没有考虑到的。由于我们在dp表中表示不出来,那我们就在计算的时候单独拿出来这种情况计算,即i和j相邻的时候:
for(int i = s.length()-1; i>=0; i--){ for(int j = i+1; j<s.length(); j++){ if(s.charAt(i) == s.charAt(j)){ //i和j相邻的时候 if(j - i == 1){ dp[i][j] = true; } else{ dp[i][j] = dp[i+1][j-1] } } else{ dp[i][j] = false; } } }由于最终需要输出最长的回文子串,我们在遍历的时候记录一下即可。
import java.util.Arrays; class Solution { public String longestPalindrome(String s) { if(s == null || s.equals("")){ return s; } boolean[][] dp = new boolean[s.length()][s.length()]; int[] result = new int[2]; for(int i = 0; i<s.length(); i++) dp[i][i] = true; for(int i = s.length()-1; i>=0; i--){ for(int j = i+1; j<s.length(); j++){ if(s.charAt(i) == s.charAt(j)) { if(j-i == 1){ dp[i][j] = true; } else{ dp[i][j] = dp[i+1][j-1]; } }else{ dp[i][j] = false; } if(dp[i][j]){ if(result[1]-result[0] <= j - i){ result[0] = i; result[1] = j; } } } } return s.substring(result[0],result[1]+1); } }作者:Geralt_U 链接:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/5-zui-chang-hui-wen-zi-chuan-dong-tai-gui-hua-jie-/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。