1、题目描述
多多在玩一个游戏,他想要从一堆字符串中构造出一个新的字符串,具体规则如下:
给定 N 个字符串,多多可以从第i字符串中提取出最多 X;个字符,被取出字符可以按任意顺序拼接成一个长度为 K的新字符串T,但多多希望这个字符串的字典序尽可能的小。
请问多多最终得到的新字符串是什么?
输入描述
第一行,两个整数 N 和 K,表示有 N 字符串以及目标串T的长度接下来N行,第i行有一个字符串和一个整数:S,X;S;是第i个字符串
X;是要求第i个字符串取出的字符个数
1 <=N<= 10001 <= |S;| <= 1000
0 <= X; <= |Si
0 <= K<= ∑X;<= 1000,000
输出描述
个字符串 T
示例 1
输入:
23
abb 2
ccaa 1
输出:
aab
说明
从第2个字符串中取出 a,第1个字符串中取出a和b,拼接成aab的字典序最小
2、解题思路
要解决这个问题,我们需要从给定的N个字符串中,每个字符串最多取出Xi个字符,然后按照字典序最小的方式组合成一个长度为K的新字符串。关键在于如何高效地选择这些字符,使得最终的字符串字典序最小。
方法思路
-
收集所有可用字符:首先,我们需要从每个字符串中收集最多Xi个字符。对于每个字符串Si,我们取出其中最小的Xi个字符(因为最小的字符在前面的位置可以使得整个字符串的字典序最小)。
-
合并和排序字符:将所有收集到的字符合并到一个列表中,并按字典序排序。这样,我们可以按顺序选择最小的字符来构建结果字符串。
-
构建结果字符串:从排序后的字符列表中取出前K个字符,并按顺序拼接成字符串,即为字典序最小的字符串。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
int K = scanner.nextInt();
scanner.nextLine(); // 换行
List<Character> chars = new ArrayList<>(); //定义list来存放每个字符串获取的xi个的字符
for (int i = 0; i < N; i++) {
String line = scanner.nextLine();
String[] parts = line.split(" ");
String s = parts[0]; //获取字符串
int x = Integer.parseInt(parts[1]); //获取xi
if (x == 0) continue;
char[] arr = s.toCharArray();
Arrays.sort(arr); //将字符进行排序,下面只需要获取xi个最小的字符即可,再后续拼接
for (int j = 0; j < Math.min(x, arr.length); j++) {
chars.add(arr[j]); //将获取的xi个字符存入list,拼接在一起
}
}
Collections.sort(chars);//对拼接得到的字符进行排序
StringBuilder sb = new StringBuilder();
for (int i = 0; i < K; i++) { //获取前k个字符
sb.append(chars.get(i));
}
System.out.println(sb.toString());
}
}
代码解释
-
输入处理:读取输入的字符串数量N和目标字符串长度K。然后逐行处理每个字符串和对应的数字Xi。
-
字符收集与排序:对于每个字符串Si,将其转换为字符数组并排序,这样最小的字符会排在前面。然后,将前Xi个字符(或全部字符,如果Xi超过字符串长度)添加到字符列表中。
-
全局排序:将所有收集到的字符进行全局排序,以确保字符按字典序排列。
-
构建结果字符串:从排序后的字符列表中取出前K个字符,拼接成最终的字符串并输出。
这种方法确保了我们总是使用当前可用的最小字符来构建结果字符串,从而保证字典序最小。时间复杂度主要由排序步骤决定,全局排序的时间复杂度为O(M log M),其中M是所有字符的总数(最多1,000,000),这在给定的约束下是可行的。
83

被折叠的 条评论
为什么被折叠?



