3804. 构造字符串-AcWing题库

作者 : Xia Xinyu
日期 : 2021-08-14

原题链接

题目:

给定一个长度为 n 的由小写字母构成的字符串 s。

请你构造一个长度为 k 的由小写字母构成的字符串 t。

要求,字符串 t 需满足:

字符串 t 在字典序上大于字符串 s。
字符串 t 的字母集是字符串 s 的字母集的子集。一个字符串的字母集是指该字符串包含的所有不同字母的集合,例如 abadaba 的字母集为 {a,b,d}。
字符串 t 在字典序上尽可能小。
保证答案存在。

输入格式
第一行包含整数 T,表示共有 T 组测试数据。

每组数据第一行包含两个整数 n 和 k。

第二行包含一个长度为 n 的字符串表示 s。

输出格式
每组数据输出一行满足所有条件的字符串 t。

数据范围
前三个测试点满足 1≤n,k≤3。
所有测试点满足 1≤T≤10,1≤n,k≤105。
同一测试点内,所有 n 的和不超过 105,所有 k 的和不超过 105。

输入样例:

4
3 3
abc
3 2
abc
3 3
ayy
2 3
ba

输出样例:

aca
ac
yaa
baa

思路:分两种情况进行讨论即可

1:若n < k 则原样输出s串,然后再输出s串中最小字符 k - n 次即可

2:若 n >= k,这时需要从后往前遍历,若当前字符可以找到下一个比自身大的字符就更换(找到后即可跳出循环),否则变成s串中最小字符(因为满足条件——可以找到下一个比自身大的字符后面的字符不影响字典序的大小,所以为满足条件取最小字符即可)

代码:

import java.util.*;
public class Main{
    public static char get_min(boolean[] flag){
        for(int i = 0;i < flag.length;i++)
            {
                if(flag[i] == true)
                    {
                        return (char)(i + 'a');
                    }
            }
            return 0;
    }
    public static char get_next(boolean[] flag,int index){
        int i = index;
        for(i = index;i < 26;i++)
            {
                if(flag[i]) return (char)('a' + i);
            }
        if(i == 26) return 'f';
        return 0;
    }

    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int T = in.nextInt();
        while(T-- != 0){
            int n = in.nextInt();
            int k = in.nextInt();
            String s = in.next();
            var c = s.toCharArray();
            var flag = new boolean[26];
            for(int i = 0;i < c.length;i++) 
                {
                    flag[c[i] - 'a'] = true;
                }
            if(k > n){
                for(char x : c) System.out.print(x);
                for(int i = 1;i <= k - n;i++) System.out.print(get_min(flag));
            }

            else{

                boolean f = false;
                int index = 0;
                for(int i = k - 1;i >= 0;i--){
                    if(get_next(flag,c[i] - 'a' + 1) != 'f')
                        {
                            c[i] = get_next(flag,c[i] - 'a' + 1);
                            break;
                        }
                    else 
                        c[i] = get_min(flag);
                }
                for(int i = 0;i < k;i++) System.out.print(c[i]);
            }
            System.out.println();
        }
    }
}

时间复杂度:O(n)

空间复杂度:O(n)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XiaXinyuuu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值