Java升序整数数组缺失数字查找的优化方案咨询
升序整数数组缺失数字的更优实现方案咨询
我自学Java仅3周,通过YouTube视频和博客学习,Java是我的第一门编程语言。我想写一个程序查找升序整数数组中的缺失数字,但找到的方法只在数组末尾数字小于10时有效,网上其他方案也有同样问题。我凭着有限知识写出了可行但冗长的代码(约27行),尝试优化代码美观性后反而变得更庞大,以下是我的代码及输出,想请教有没有更优的实现方式。
测试数组为[12, 13, 17, 18, 20, 21, 24, 25, 26],其中缺失的数字是14、15、16、19、22、23。
第一版:可行但冗长的代码
import java.util.Arrays; public class Exercises { public static void main(String[] args) { int[] arr = {12, 13, 17, 18, 20, 21, 24, 25, 26}; int len = arr.length; System.out.println("\nArray source: \n" + Arrays.toString(arr)); // 为避免数组越界,创建临时数组并复制原数组元素 int[] tempArr = new int[len + 1]; for (int i = 0; i < len; i++) { tempArr[i] = arr[i]; } // 找出最大值并给临时数组最后一位赋值max+1 int max = 0; for (int i = 0; i < tempArr.length; i++) { if (tempArr[i] > max) { max = tempArr[i]; } } tempArr[tempArr.length - 1] = max + 1; System.out.println("\nMissing number(S): "); for (int i = 0; i < len - 1; i++) { // 处理原数组最后一位的情况,用临时数组的最后一位比较 if (i == (len - 1) && (tempArr[i + 1] - arr[i]) > 1) { System.out.println(tempArr[i]); } else if ((arr[i + 1] - arr[i]) > 1) { for (int a = 1; a <= (arr[i + 1] - arr[i]) - 1; a++) { System.out.println(arr[i] + a); } } } } }
输出结果
Array source: [12, 13, 17, 18, 20, 21, 24, 25, 26] Missing number(S): 14 15 16 19 22 23
我得到了正确结果,但代码太冗长,有没有更优的实现方式?
第二版:追求美观但更庞大的代码
import java.util.Arrays; public class Exercises { public static void main(String[] args) { int[] arr = {12, 13, 17, 18, 20, 21, 24, 25, 26}; int len = arr.length; int[] tempArr = new int[len + 1]; int[] correctArr = new int[Arrays.stream(arr).max().getAsInt() - Arrays.stream(arr).min().getAsInt() + 1]; int countArr = (Arrays.stream(arr).max().getAsInt() - (Arrays.stream(arr).max().getAsInt() - Arrays.stream(arr).min().getAsInt()) - 1); for (int i = 0; i < correctArr.length; i++) { countArr++; correctArr[i] = countArr; } System.out.println("\nArray source: \n" + Arrays.toString(arr)); System.out.println("Source should be: \n" + Arrays.toString(correctArr)); for (int i = 0; i < len; i++) { tempArr[i] = arr[i]; } int max = 0; for (int i = 0; i < tempArr.length; i++) { if (tempArr[i] > max) { max = tempArr[i]; } } tempArr[tempArr.length - 1] = max + 1; int count = 0; for (int i = 0; i < len - 1; i++) { if (i == (len - 1) && (tempArr[i + 1] - arr[i]) > 1) { count++; } else if ((arr[i + 1] - arr[i]) > 1) { for (int a = 1; a <= (arr[i + 1] - arr[i]) - 1; a++) { count++; } } } if (count == 1) { System.out.println("\nThere is only one missing number:"); } else if (count > 1) { System.out.println("\nThere are " + count + " missing numbers:"); } for (int i = 0; i < len - 1; i++) { if (i == (len - 1) && (tempArr[i + 1] - arr[i]) > 1) { System.out.println(tempArr[i]); } else if ((arr[i + 1] - arr[i]) > 1) { for (int a = 1; a <= (arr[i + 1] - arr[i]) - 1; a++) { System.out.println(arr[i] + a); } } } } }
输出结果
Array source: [12, 13, 17, 18, 20, 21, 24, 25, 26] Source should be: [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26] There are 6 missing numbers: 14 15 16 19 22 23
优化后的实现方案
可以简化逻辑,去掉冗余的临时数组,直接遍历相邻元素计算差值,同时用集合统一收集缺失数字,让代码更简洁易读:
import java.util.Arrays; import java.util.ArrayList; import java.util.List; public class FindMissingNumbers { public static void main(String[] args) { int[] arr = {12, 13, 17, 18, 20, 21, 24, 25, 26}; System.out.println("原数组: " + Arrays.toString(arr)); List<Integer> missingNumbers = new ArrayList<>(); // 遍历相邻元素,无需担心越界(遍历到倒数第二个元素即可) for (int i = 0; i < arr.length - 1; i++) { int current = arr[i]; int next = arr[i + 1]; // 差值大于1时,收集中间的缺失数字 if (next - current > 1) { for (int num = current + 1; num < next; num++) { missingNumbers.add(num); } } } // 统一输出结果 if (missingNumbers.isEmpty()) { System.out.println("没有缺失数字"); } else { System.out.printf("缺失的数字共%d个:\n", missingNumbers.size()); missingNumbers.forEach(System.out::println); } } }
优化思路说明
- 移除冗余临时数组:直接遍历到原数组的倒数第二个元素,避免越界问题,无需额外数组。
- 集合统一收集结果:避免多次打印操作,逻辑更清晰,也方便后续对缺失数字做其他处理。
- 可扩展封装:如果需要复用查找逻辑,可以把核心代码封装成独立方法:
public static List<Integer> findMissingNumbers(int[] sortedArr) { List<Integer> missing = new ArrayList<>(); for (int i = 0; i < sortedArr.length - 1; i++) { int current = sortedArr[i]; int next = sortedArr[i + 1]; for (int num = current + 1; num < next; num++) { missing.add(num); } } return missing; } - 兼容任意升序数组:该方案不受数组末尾数字大小限制,适用于所有升序整数数组。
内容的提问来源于stack exchange,提问作者Kanan Bashirov
相关产品推荐
相关产品推荐

