博客主页:JavaProfessional
一个专注于Java的博主,致力于使用通俗易懂的语句讲解内容,期待您的关注!
编程第一题:小艺的英文名
一、题目名称:小艺的英文名
时间限制:1000ms内存限制:256M
题目描述:
小艺酱想给自己起—个英文名字。小艺酱想要装的自己学识渊博。所以她想要自己英文名字必须满足:
1.只有字母表中前k个小写字母。
2必须是回文串。
3.前k个小写字母每个字母至少出现—次。
小艺酱已经自己完成了部分空余的字母部分用’?’代替。
请你帮她完成她的英文名字。
输入描述:
第一行输入一个整数k。(1第二行输入小艺酱的英文名字name。(1
输出描述:
如果小艺的名字不存在输出“QAQ",如果存在多组解,输出字典序最小的一个解。
示例
输入
2
a??a
输出
abba
思路:双指针
- 为了确保第1点和第3点,我们需要知道已经给出的字母中有哪些字母已经出现过,有哪些字母还没有出现过
- 为了保证回文串,我们可以从两端向中间处理,也可以从中间向两端处理。
- 题目中还有一点要求,如果存在多组解,我们要输出字典序最小的一个解,所以我们选择从中间向两端处理,当所有字母都已经出现过,其余?我们填充字典最小a即可满足。
代码:
public class Name {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextInt()) {
Integer count = scanner.nextInt();
scanner.nextLine();
String template = scanner.nextLine();
// 获取所有的字母
List<Character> allCharacter = new LinkedList<>();
for (Integer i = count - 1; i >= 0; i--) {
allCharacter.add((char) ('a' + i));
}
List<Character> exist = new LinkedList<>();
for (int i = 0; i < template.length(); i++) {
exist.add(template.charAt(i));
}
// 剩下的就是需要至少出现一次的字母,已经倒序排好了
allCharacter.removeAll(exist);
int left = template.length() % 2 == 0 ? template.length() / 2 - 1 : template.length() / 2;
int right = template.length() / 2;
//左右指针从中间开始倒序插入
int index = 0;
char[] newStr = new char[template.length()];
while(left>=0 && right<template.length() && index<allCharacter.size()) {
if (template.charAt(left)=='?' && '?' == (template.charAt(right))) {
newStr[left] = allCharacter.get(index);
newStr[right] = allCharacter.get(index);
index++;
} else {
newStr[left] = template.charAt(left);
newStr[right] = template.charAt(right);
}
left--;
right++;
}
// 所有的字母都用完了(已经满足了条件3),但是回文还没走到头,那么剩下的只需要都赋值为‘a’即可(这样满足最小字典序)
while (left>=0 ||right<template.length()) {
if (template.charAt(left)=='?' && '?' == (template.charAt(right))) {
newStr[left] = 'a';
newStr[right] = 'a';
index++;
} else {
newStr[left] = template.charAt(left);
newStr[right] = template.charAt(right);
}
left--;
right++;
}
// 序列都走到头了,字母还没用完,则不满足条件3
if (index <allCharacter.size()) {
System.out.println("QAQ");
return;
}
System.out.println(new String(newStr));
}
scanner.close();
return;
}
}
结果
输入输出1
上图输入输出其实是一个最正常的结果。
输入输出2
上图输入输出其实是输入输出1的变形,我们把所有的字母都完美的用上了。
输入输出3
该用例是指字母多于空位,形不成回文
输入输出4
该用例恰好能形成回文。
输入输出5
该用例是验证最小字典序
输入输出6
该用例同样是验证最小字典序,且所给的字母小于?的个数。