删除部分字符使其变成回文串-最长公共子序列

给定一个字符串str,删除部分字符使其变成回文串,问最少删除多少字符可以变成回文串,即最长回文串。(腾讯笔试题)

这个问题可以进行转化:
将str进行反转,得到str1,只需比较str和str1的最长公共子序列即可。求出最长公共子序列之后,将str的长度减去最长公共子序列的长度就是需要删除的字符数。

采用动态规划的方法求最长公共子序列。记字符串a(长度为i),字符串b(长度为j)的最长公共子序列为c[i][j],用一个二维数组存放。于是有下面的递推公式。


删除部分字符使其变成回文串-最长公共子序列_第1张图片
image.png

java代码(实现腾讯笔试题)

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Solution s = new Solution();
        Scanner sc = new Scanner(System.in);
        while(sc.hasNextLine()) {
            System.out.println( s.getResult(sc.nextLine()) );
        }
        sc.close();
    }
}

class Solution {
    public int getResult(String s) {
        StringBuilder s1 = new StringBuilder(s);
        StringBuilder s2 = new StringBuilder(s).reverse();
        return s.length() - LCS(s1, s2);
    }
    public int LCS(StringBuilder s1, StringBuilder s2) {
        int m = s1.length();
        int n = s2.length();
        int[][] mutrix = new int[m + 1][n + 1];
        
        for(int i = 1; i <= m; i++) {
            for(int j = 1; j <= n; j++) {
                if(s1.charAt(i - 1) == s2.charAt(j - 1))
                    mutrix[i][j] = mutrix[i - 1][j - 1] + 1;
                else 
                    mutrix[i][j] = Math.max(mutrix[i - 1][j], mutrix[i][j - 1]);
            }
        }
        return mutrix[m][n];
    }
}

c语言代码(实现最长公共子序列)(递归)

#include 
#include 
int c[200][200];
char x[200],y[200];
int max(int a,int b){
    if(a>b) return a;
    return b;
}
int lcs(int lenx,int leny){
    if(lenx==0||leny==0) return 0;
    if(x[lenx-1]==y[leny-1]) return lcs(lenx-1,leny-1)+1;
    return max(lcs(lenx,leny-1),lcs(lenx-1,leny));
}
int main(){
    scanf("%s%s",x,y);
    int lenx,leny;
    lenx = strlen(x);
    leny = strlen(y);
    printf("%d",lcs(lenx,leny));
    return 0;
}

c语言代码(实现最长公共子序列)(利用二维数组)

#include 
#include 
int c[200][200];
int max(int a,int b){
    if(a>b) return a;
    return b;
}
int main(){
    char x[200],y[200];
    scanf("%s%s",x,y);
    int lenx,leny,i,j;
    lenx = strlen(x);
    leny = strlen(y);
    for(i=1;i<=lenx;i++){
        for(j=1;j<=leny;j++){
            if(x[i]==y[j]) c[i][j] = c[i-1][j-1]+1;
            else c[i][j] = max(c[i][j-1],c[i-1][j]);
        }
    }
    printf("%d",c[lenx][leny]);
    return 0;
}

你可能感兴趣的:(删除部分字符使其变成回文串-最长公共子序列)