Leetcode 5.最长回文子串
动态规划:
1
class Solution { 2 public String longestPalindrome(String s) { 3 int len=s.length(); 4 if(len==0)return s; 5 boolean dp[][]=new boolean[len][len];//dp数组表示在两个下标之间的子串是不是回文串 6 int maxLen=0;//记录最大长度 7 String res=null; 8 for (int i = len-1; i >=0; i--) {//因为dp依赖与中间的dp值,所以i从尾到头遍历 9 for (int j = i; j < len; j++) { 10 //如果头尾两个值一样,并且头尾不是相邻时,依赖于中间dp值。 11 //中间如果只有一个字母,那必为回文,所以判断j-1<3 12 dp[i][j]=s.charAt(i)==s.charAt(j)&&(j-i<3||dp[i+1][j-1]); 13 //找最长 14 if(dp[i][j]&&(res==null||j-i>maxLen)){ 15 res=s.substring(i,j+1);//此处可优化,只记录当前最小子串左右下标,最后在取子串 16 maxLen=j-i; 17 } 18 } 19 } 20 return res; 21 } 22 }
压缩空间复杂度
相当于使用j-1位置的数据
故可以压缩空间
tmp=未更新值
更新值为前一个
prev=tmp
1 class Solution { 2 public String longestPalindrome(String s) { 3 if(s.length()==0)return ""; 4 boolean[] dp =new boolean[s.length()]; 5 int max_len=1; 6 String res=s.substring(0,1); 7 for (int i = dp.length-1; i>=0; i--) { 8 boolean prev=false;//注意prev是每次j的循环使用的共享变量 9 for (int j=i;j<dp.length;j++){ 10 if(i==j){ 11 dp[j]=true; 12 } 13 else if(j-i==1){ 14 prev=dp[j]; 15 dp[j]=(s.charAt(i)==s.charAt(j)); 16 } 17 else if(i+1<dp.length&&j>0){ 18 boolean tmp=dp[j]; 19 if(s.charAt(i)==s.charAt(j)){ 20 dp[j]=prev; 21 } 22 else { 23 dp[j]=false; 24 } 25 prev=tmp; 26 } 27 if(dp[j]&&j-i+1>max_len){ 28 max_len=j-i+1; 29 res=s.substring(i,j+1); 30 } 31 } 32 } 33 return res; 34 } 35 }