给定一个字符串str,如果可以在str的任意位置添加字符,请返回在添加字符最少的情况下,让str整体都是回文字符串的一种结果。
思路:该题可以采用动态规划解决,创建矩阵dp[i][j],如果str[i]==str[j],则dp[i][j]=0,如果str[i]!=str[j],dp[i][j]=min{dp[i+1][j],dp[i][j-1]}+1;其中矩阵表示添加字符的最少数量。具体代码实现如下所示:
public class GetPalindromel { public int[][] getDP(char[] str){ int[][] dp=new int[str.length][str.length]; for (int j=1;j<str.length;j++){ dp[j-1][j] = str[j-1] == str[j] ? 0:1; for (int i=j-2;i>-1;i--){ if (str[i]==str[j]){ dp[i][j]=dp[i+1][j-1]; }else{ dp[i][j]=Math.min(dp[i+1][j],dp[i][j-1])+1; } } } return dp; } public String getPalindromel(String str){ if (str==null || str.length()<2){ return str; } char[] chs=str.toCharArray(); int[][] dp=getDP(chs); char[] res=new char[dp[0][chs.length-1] + chs.length]; int i=0; int j=chs.length-1; int resi=0; int resj=res.length-1; while(i<=j){ if (chs[i]==chs[j]){ res[resi++]=chs[i++]; res[resj--]=chs[j--]; }else if (dp[i][j-1]<dp[i+1][j]){ res[resi++]=chs[j]; res[resj--]=chs[j--]; }else{ res[resj--]=chs[i]; res[resi++]=chs[i++]; } } return String.valueOf(res); } public static void main(String[] args) { String str="A1B21C"; GetPalindromel getPalindromel=new GetPalindromel(); String palindromel = getPalindromel.getPalindromel(str); System.out.println(palindromel); } }
求解dp矩阵的时间复杂度为O(),根据str和dp矩阵求解最终结果的过程为O(N),所以该问题最终的时间复杂度为O()。
进阶题目:
给定一个字符串str,再给定str的最长回文子序列字符串strlps,请返回在添加字符最少的情况,让str整体都是回文字符串的一种结果。
该问题相比较上一题增加了一个指定字符串,借用左神的说法就是采用“剥洋葱”的方法解决,根据给定字符串strlps,一层一层的剥,由于在求解结果的时候只是遍历两个指定的字符串数组,这样的话时间复杂度可加速到O(N),具体代码实现如下所示:
public class GetPalindromel2 { public String getPalindromel2(String str,String strlps){ if (str==null||str.equals(" ")){ return ""; } char[] chs=str.toCharArray(); char[] lps=strlps.toCharArray(); char[] res=new char[2*chs.length-lps.length]; int chsl=0; int chsr=chs.length-1; int lpsl=0; int lpsr=lps.length-1; int resl=0; int resr=res.length-1; int tmpl=0; int tmpr=0; while(lpsl<=lpsr){ tmpl=chsl; tmpr=chsr; while(chs[chsl]!=lps[lpsl]){ chsl++; } while(chs[chsr]!=lps[lpsr]){ chsr--; } set(res,resl,resr,chs,tmpl,chsl,chsr,tmpr); resl+=chsl-tmpl+tmpr-chsr; resr-=chsl-tmpl+tmpr-chsr; res[resl++]=chs[chsl++]; res[resr--]=chs[chsr--]; lpsl++; lpsr--; } return String.valueOf(res); } private void set(char[] res, int resl, int resr, char[] chs, int tmpl, int chsl, int chsr, int tmpr) { for (int i=tmpl;i<chsl;i++){ res[resl++]=chs[i]; res[resr--]=chs[i]; } for (int i=tmpr;i>chsr;i--){ res[resl++]=chs[i]; res[resr--]=chs[i]; } } public static void main(String[] args) { String str="A1BC22DE1F"; String slp="1221"; GetPalindromel2 getPalindromel2=new GetPalindromel2(); String palindromel2 = getPalindromel2.getPalindromel2(str, slp); System.out.println(palindromel2); } }