您的位置:首页 > 其它

2016腾讯笔试题,删除字符串中的字符,使得剩下的字符串是回文串,如何删除使得回文串最长

2016-09-10 23:33 387 查看
给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
输出需要删除的字符个数。


输入描述:


输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.


输出描述:


对于每组数据,输出一个整数,代表最少需要删除的字符个数。


输入例子:

abcda
google



输出例子:

2
2
思路:回文串的特点是,逆序输出和正序输出是一样的。所以这道题可以从这方面来考虑。如果将此字符串逆序输出,那么两个字符串的最长公共子序列将是最长的回文字符串,那么剩余的值将是要删除的字符个数。求LCS的方法可以在csdn中找到。

import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
while(scan.hasNext()){
String str = scan.nextLine();
System.out.println(str.length()-getResult(str));
}
}
public static int getResult(String str){
StringBuilder sb  = new StringBuilder(str);
String newStr = sb.reverse().toString();
char[] c1 = str.toCharArray();
char[] c2 = newStr.toCharArray();
int n = str.length();
int[][] dp = new int[n+1][n+1];
for(int i=1;i<n+1;i++){
for(int j=1;j<n+1;j++){
if(c1[i-1]==c2[j-1]){ //此处应该减1.
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
}
}
}
return dp

;
}
}

此题是组合优化问题,求解过程是多步判断,从小到大求解每个子问题,最后求解的子问题就是原始问题,满足最优子结构性质,因此使用动态规划算法求解。
求解过程中需要保存子问题的中间结果,以备用来求大问题的解。使用二维数组huiWenLen[i][j]保存字符串中下标i到j的子字符串中最长回文长度。

初始条件:if(i==j) huiWenLen[i][j] = 1;
如果str.charAt(i) = str.charAt(j),当然如果i到j只有2个字符,huiWenLen[i][j] = 2;huiWenLen[i][j] = huiWenLen[i+1[j-1];
如果str.charAt(i)!=str.charAt(j);huiWenLen[i][j] = max{huiWenLen[i+1][j],huiWenLen[i][j-1]};

有了递推式之后就可以使用迭代来求解了。

public int maxHuiWenLen(String str){//获取字符串的长度        int strLen = str.length();//二维数组huiWenLen[i][j]用来保存字符串下标i到j子串的最长回文长度        int huiWenLen[][] = new int[strLen][strLen];//for循环用来填写二维数组        for(int k=0;k<strLen;k++){            for(int i=0,j=k;i<strLen-k;i++,j++){//当只有一个字符时,回文长度为1                if(i==j){
                    huiWenLen[i][j] = 1;                }else{//如果字符串中下标为i的字符和下标为j的字符相同,则,huiWenLen[i][j] = huiWenLen[i+1][j-1] + 2;//如果i,j之间只有2个字符,则huiWenLen[i][j] = 2;                    if(str.charAt(i)==str.charAt(j)){
                        if(j-i==1){
                           huiWenLen[i][j] = 2;
                        }else{
                           huiWenLen[i][j] = huiWenLen[i+1][j-1] + 2;
                        }                    }else{//用已经获得的小问题的中间结果求解大问题                        if(a[i+1][j]>a[i][j-1]){
                           huiWenLeni][j] = huiWenLen[i+1][j];
                        }else{
                            huiWenLen[i][j] = huiWenLen[i][j-1];
                        }
                    }
                }
            }        }//返回要删除的字符个数,使得回文最长        return strLen-huiWenLen[0][strLen-1];
    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐