04头条笔试_字母交换

【编码题】字符串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连续出现。

思路:动态规划

步骤:(1)先将字母及字母出现的位置存储在二维数组binStr[][]中,行表示字符串的第i个位置,列表示对应的字母;

(2)逐次取出每个字母(最多26个),将其出现位置存储在一维数组location[]中;

(3)然后通过动态规划方法,从少到多将相同字母交换相近,如果交换次数没有超出限制,则检查此时交换后相同连续出现的字母是不是最长。

各个字母在限制内移动次数得到的最大长度保存在num[]数组中。

package Practise;

import java.util.Scanner;

public class Main2 {
    public static int dp(int i,int j,int[] location){
        if(i==j){
            return 0;
        }
        else if(i+1==j){
            return location[j]-location[i]-1;
        }
        else {
            //(j-i-1)表示中间还有相同字母个数(相当于i+1=j时中间相同字母个数为0)
            return dp(i+1,j-1,location)+location[j]-location[i]-(j-i-1)-1;
        }
    }
    public static void main(String [] args){
        Scanner sc = new Scanner(System.in);
        String str = sc.next();
        int len = str.length();
        char[] arrStr = str.toCharArray();
        int m = sc.nextInt();
        int[][] binStr= new int[arrStr.length][26];
        for(int i = 0;i <arrStr.length;i++){
            binStr[i][arrStr[i]-'a'] =1;
        }
//        for(int i = 0;i <binStr.length;i++ ){
//            for(int j = 0;j < 26 ;j++){
//                System.out.print(binStr[i][j]);
//            }
//            System.out.println();
//        }
        int[] num = new int[26];//记录每个字母最长数量(规定移动次数范围内)
        for(int j = 0;j < 26 ;j++){//第i个字母
            int[] location = new int[len];
            int k = 0;
            for(int i =0 ;i<len;i++){
                if(binStr[i][j]==1)
                    location[k++] = i;
            }
            if(k == 1){//字符串中只有一个字母
                num[j] = 1;
            }
            else{
                int temp = -1;
                for(int i = 0;i < k;i++){
                    for(int ii = i+1;ii<k;ii++){
                        int re = dp(i,ii,location);
                        if(re<=m){
                            if(ii-i+1>temp){
                                temp = ii-i+1;
                            }
                        }
                    }
                }
                num[j] = temp;
            }
        }
        int sum = num[0];
        for(int i = 1;i<26;i++){
            if(num[i]>sum){
                sum = num[i];
            }
        }
        System.out.println(sum);
    }
}

猜你喜欢

转载自blog.csdn.net/FJJ543/article/details/81543608