美文网首页
【腾讯】给定一个字符串s,你可以从中删除一些字符,使得剩下的串是

【腾讯】给定一个字符串s,你可以从中删除一些字符,使得剩下的串是

作者: 欧德朗 | 来源:发表于2018-10-16 09:45 被阅读0次

    2018-10-15

    题目

    /给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
    输出需要删除的字符个数。
    输入描述:
    输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.
    输出描述:
    对于每组数据,输出一个整数,代表最少需要删除的字符个数。
    输入例子1:
    abcda
    google
    输出例子1:
    2
    2
    /
    解题思路:先将字符串翻转,再求两个字符创的最大公共子序列,然后就可以知道应该删除那些字符。
    ps:注意公共子序列和公共子串是不一样的,
    最长公共子串(Longest Common Substring)与最长公共子序列(Longest Common Subsequence)的区别: 子串要求在原字符串中是连续的,而子序列则只需保持相对顺序一致,并不要求连续。例如X = {a, Q, 1, 1}; Y = {a, 1, 1, d, f}那么,{a, 1, 1}是X和Y的最长公共子序列,但不是它们的最长公共字串。
    以上摘自博客.
    字符串的翻转简单做法:

    #include<algorithm>
    string str;
    cin>> str;
    reverse(str.begin(),str.end());
    cout<< str <<endl;
    

    以上即可将字符串翻转输出。
    剩下的问题就变成了,怎么求得最大公共子序列问题
    还是动态规划问题,需要研究一下,这个问题。
    参考上面博客
    还有直接解决问题的大佬博客

    代码如下

    #include <iostream>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    
    const int MAXN=1010;
    int temp[MAXN][MAXN];
    
    //先求s的反串reverse,然后求他们的最长的公共子序列,要删除的字符个数就能知道
    //时间复杂度O(N^2)
    
    int getRemoveNumber(string &s1)
    {
        string s2(s1);
        reverse(s2.begin(),s2.end());
        int len=s1.length();
        memset(temp,0,sizeof temp);//讲二维数组全部替换成0
        for(int i=0;i<len;++i)
        {
            for(int j=0;j<len;++j)
            {
                if(s1[i]==s2[j])
                    //判断如果遍历到相等的字符,
                    temp[i+1][j+1]=temp[i][j]+1;
                else temp[i+1][j+1]=max(temp[i][j+1],temp[i+1][j]);
            }
        }
        return len-temp[len][len];
    }
    
    int main()
    {
       string s;
       while(cin>>s)
       {
           cout<<getRemoveNumber(s)<<endl;
       }
       return 0;
    }
     
    

    这个好像也挺强
    特么的看不懂
    以上

    相关文章

      网友评论

          本文标题:【腾讯】给定一个字符串s,你可以从中删除一些字符,使得剩下的串是

          本文链接:https://www.haomeiwen.com/subject/ungfzftx.html