今日头条笔试之字母交换

一、题目描述

【编码题】字符串S由小写字母构成,长度为n。定义一种操作,每次都可以挑选字符串中任意的两个相邻字母进行交换。询问在至多交换m次之后,字符串中最多有多少个连续的位置上的字母相同?

输入描述:
第一行为一个字符串S与一个非负整数m。(1 <= |S| <= 1000, 1 <= m <= 1000000)


输出描述:
一个非负整数,表示操作之后,连续最长的相同字母数量。

输入例子1:
abcbaa 2

输出例子1:
2

例子说明1:
使2个字母a连续出现,至少需要3次操作。即把第1个位置上的a移动到第4个位置。
所以在至多操作2次的情况下,最多只能使2个b或2个a连续出现。

二、解题思路

设置一个字符串长x26大小的二维数组,对于字符串中的每个字母,记录其出现的位置,将对应的矩阵元素设置为1,其余元素为0,然后按列优先遍历矩阵,将每个字母出现的位置下标记录到一个数组里,计算将i和j之间的相同元素全部移动到一起需要的最小移动次数,在这个最小次数满足满足约束条件的前提下,筛选出最大的连续字母的个数。最后比较所有字母的最大连续个数,输出其中的最大值即可。难点在于计算将i和j之间的相同元素全部移动到一起需要的最小移动次数,这里的核心思想就是使用动态规划得到转移方程,只要能想到这一点,问题就迎刃而解了。

三、AC代码

#include <iostream>
#include <string.h>
#include <algorithm>
#define N 26
using namespace std;

//dynamic programming
int dp(int i,int j,int a[])
{
    if(i == j)
    {
        return 0;
    }
    else if(i+1 == j){
        return a[j]-a[i]-1;
    }
    else{
        //当一个字母出现多次且不连续时,应该从两侧往中间移,这样才能保证移动次数最少。找规律得到状态转移方程
        return dp(i+1,j-1,a)+a[j]-a[i]-(j-i);
    }
}

int main()
{
    string str;
    int num;
    cin >> str >> num;
    int length = str.length();
    int a[length][N];
    int b[N]; //存放各字母在满足约束的情况下最大的连续数
    int m[length];
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    memset(m,0,sizeof(m));
    //lengthx26的矩阵,出现字母的地方都置1
    for(int i=0;i<length;i++)
    {
        for(int j=0;j<N;j++)
        {
            a[i][str[i]-'a'] = 1;
        }

    }

    for(int j=0;j<N;j++)
    {
        int k=0;
        for(int i=0;i<length;i++)
        {
            if(a[i][j] == 1)
            {
                m[k++] = i;
            }

        }

        if(k == 1)
        {
            b[j] = 1;
        }
        else
        {
            int temp=-1;
            for(int i=0;i<k;i++)
            {
                for(int ii=i+1;ii<k;ii++)
                {
                    if( dp(i,ii,m)<= num )
                    {
                        if((ii-i)+1> temp)
                            temp = (ii-i)+1;
                    }
                }
            }
            b[j] = temp;
        }

    }
    sort(b,b+N);
    cout << b[N-1] << endl;
    return 0;
}


猜你喜欢

转载自blog.csdn.net/cxzzxc123456/article/details/79058419
今日推荐