题目:1204. 错误票据 - AcWing题库https://www.acwing.com/problem/content/description/1206/
import java.util.Scanner;
public class Main {
public static void main(String args[]){
Scanner input = new Scanner(System.in);
int line = input.nextInt();
int loseId = -1;
int repeatId = -1;
//数据处理
StringBuilder ID = new StringBuilder();
for(int i = 0; i <= line; i++){
String temp = input.nextLine();
ID.append(new StringBuilder(temp));
ID.append(new StringBuilder(" "));
}
String sId = ID.toString();
String[] strId = sId.split(" ");
int[] intId = new int[strId.length];
for (int i = 0; i < strId.length; i++){
try {
intId[i] = Integer.valueOf(strId[i]);
}catch (NumberFormatException e){
}
}
//冒泡排序
for(int i = 0; i < intId.length - 1; i++){
for (int j = i+1; j < intId.length; j++){
if(intId[i] > intId[j]){
int temp = intId[i];
intId[i] = intId[j];
intId[j] = temp;
}
}
}
//遍历
for(int i = 1; i < intId.length; i++){
if(intId[i] - intId[i - 1] > 1){
loseId = intId[i - 1] + 1;
}
if(intId[i] == intId[i - 1]){
repeatId = intId[i];
}
}
//输出
System.out.println(loseId + " " + repeatId);
}
}
思路:获取第一行的数值并记录在line变量中,循环line次获取每一行的ID号。使用StringBuilder对ID号进行规范化处理并将其转为int类型,然后对int类型的ID号数组进行排序。然后找出相邻两个数差值大于1的位置,即为缺失的ID;排序后,相邻的元素不相同,那么他们就不是重复元素,反之,即为重复元素。
一、准备阶段
Scanner input = new Scanner(System.in);
int line = input.nextInt();
int loseId = -1;
int repeatId = -1;
因为后续需要从键盘中输入数据,需要一个Scanner。将第一行的数据存放在line变量,表示后续有几行ID,loseId表示确实的ID号,repeatId表示重复的ID号。
二、数据处理
//数据处理
StringBuilder ID = new StringBuilder();
for(int i = 0; i <= line; i++){
String temp = input.nextLine();
ID.append(new StringBuilder(temp));
ID.append(new StringBuilder(" "));
}
String sId = ID.toString();
String[] strId = sId.split(" ");
int[] intId = new int[strId.length];
for (int i = 0; i < strId.length; i++){
try {
intId[i] = Integer.valueOf(strId[i]);
}catch (NumberFormatException e){
}
}
大概思路是,不管多少行,先把所有行全加在一起再说。因此需要一个StringBuilder用于动态增加字符串。然后通过Scanner获取到输入的字符串然后使其变为一个新的StringBuilder并统一加在ID这个变量后面。值得注意的是,有可能某一行的最后一个元素后没有跟空格,若直接链接起来,会导致上一行的最后一个数与下一行的第一数拼接在一起(如:上一行最后一个数为12,下一行的第一个数为7,若不做处理则,最后两者拼接为127)从而影响后续判断。因此,不管输入是否全都有空格,只要录入时换行我们就直接自动添加一个空格。然后将完成链接的StringBuilder转换为String类型,通过split方法对有空格处进行分割并存入int数组内。因为在前面(粉色标记)作了加空格处理,对于原本格式就对的行我们再加一个空格那就一共有两个空格,因此再split时,会导致有空缺位出现,而当空格使用Integer.valueOf()转为int类型时会报错。因为这些空格并非我们需要的数据,这些空格对实际判断没有作用,所以我们将这些错误捕获起来,不需要做处理,仅为了代码可以正常跑下去。
三、排序
//冒泡排序
for(int i = 0; i < intId.length - 1; i++){
for (int j = i+1; j < intId.length; j++){
if(intId[i] > intId[j]){
int temp = intId[i];
intId[i] = intId[j];
intId[j] = temp;
}
}
}
完成上述数据处理,现在得到一个int类型的数组存放ID。接下来就是排序,这里我使用了冒泡排序,如果想提升效率可以使用更高级一些的排序方法。将数组中的元素排好序,方便后续判断。
四、遍历并判断
//遍历
for(int i = 1; i < intId.length; i++){
if(intId[i] - intId[i - 1] > 1){
loseId = intId[i - 1] + 1;
}
if(intId[i] == intId[i - 1]){
repeatId = intId[i];
}
}
遍历这个int类型数组,进行判断。如果两个相邻的ID差值大于1,则意味着中间缺失了一个ID,将前一个值+1即可以得到loseId;因为经历了上述的排序,重复的ID必定相邻,因此只需要比对相邻的ID是否一样,如果一样则为找到重复元素了。
五、输出
//输出
System.out.println(loseId + " " + repeatId);
最后按题目要求的格式输出即可。