赞
踩
题目描述:
给你一个字符串 s,找到 s 中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。。
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”
提示:
1 <= s.length <= 1000
s 仅由数字和英文字母组成
思路:1.中心扩散法:取字符串中的字符为中心,分别向左右两边扩散,判断左右两边字符是否相等。有奇数和偶数两种情况
奇数:选择一个字符做中心
偶数:选择两个相连的字符做中心
比较奇数和偶数两种方式扩散的回文长度结果
计算对应的子串开始位置和结束位置对子串进行截取
2.动态规划法:设置一个二维矩阵dp[][]用于记录s[i…j]是不是回文串
判断dp[i][j]取决于dp[i+1][j-1]和s[i]是否等于s[j]
从两头判断,如果s[i]==s[j],那么只要判断里面的子串s[i+1…j-1]是不是回文串即可。当j-1-(s+1)-1<2,即s[i+1…j-1]长度小于2的时候,他一定是回文子串,则dp[i][j]就等于1。如果子串不是回文串,那dp[i][j]就不可能是回文串。
如果是回文串还要判断回文串的长度是不是最长的
而因为dp[i][j]取决于dp[i+1][j-1],所以要先填上dp[i+1][j-1]
例如“aaaa”

要填dp[0][3]就要知道dp[1][2],即需先知道左下角的数,才能得到答案,所以我们可以从左到右一列一列的填
//中心扩散法 class Solution { public String longestPalindrome(String s) { if(s.length()<2){ return s; } int maxlen=0; int begin=0; for(int i=0;i<s.length()-1;i++){ int oddlen=account(s,i,i); //奇数 int evenlen=account(s,i,i+1); //偶数 int len=Math.max(oddlen,evenlen); if(len>maxlen && oddlen>=evenlen) { //当奇数扩散结果比较大的时候 maxlen=len; begin=i-maxlen/2; } if(len>maxlen && oddlen<evenlen){ //当偶数扩散结果比较大的时候 maxlen=len; begin=i-maxlen/2+1; } } return s.substring(begin,begin+maxlen); } public int account(String s,int left,int right){ while(left>=0 && right<s.length()&&s.charAt(left)==s.charAt(right)){ left--; right++; } return right-left-1;//因为最后left-1了,right+1了 } }
//动态规划 class Solution { public String longestPalindrome(String s) { int len=s.length(); int[][] dp=new int[len][len]; int begin=0; int maxlen=1; //把矩阵填充 for(int i=0;i<len;i++){ dp[i][i]=1; }//对角线一定是回文的 for(int j=0;j<len;j++){//从左到右一列一列 for(int i=0;i<=j;i++){//从上到下 if(s.charAt(i)!=s.charAt(j)){ dp[i][j]=0; } else{ if(j-i<3){ dp[i][j]=1; } else{ dp[i][j]=dp[i+1][j-1]; } } if(dp[i][j]==1 && j-i+1>maxlen){ maxlen=j-i+1; begin=i; } } } return s.substring(begin,begin+maxlen); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。