如何优化这段筛选含1、2、3数字的Java代码以缩短运行时间
优化你的代码:搞定运行时间超标的问题
嘿,我看你这代码功能是实现了,但运行时间没达标对吧?咱们来拆解下问题,一步步优化:
首先明确你的需求:从整数数组里挑出包含1、2、3中至少一个数字的数,最后输出排序后的结果(没符合的就输出-1)。先看看你现有代码里拖慢速度的地方,再给你几个优化方案。
原代码的性能坑点
- 没必要修改原数组:你在循环里直接改了
a[i] = a[i]/10,虽然不影响结果,但这会破坏原数组,而且完全没必要——你都已经用temp存了原数,应该拿temp来做逐位判断,别碰原数组。 - 逐位判断的冗余操作:原代码里只要找到一个目标数字就把数加入列表,但循环条件用的是
a[i]>0,而你已经改了a[i],逻辑绕了一圈,而且逐位取模除法对于大数来说,不如直接转字符串判断高效(JVM对字符串处理有专门优化)。 - 输入处理可能拖后腿:如果测试用例的输入规模很大,
Scanner的速度其实不算快,这可能是你超时的关键原因之一。
优化后的代码方案
方案1:用字符串判断(简洁又高效)
把数字转成字符串,直接检查是否包含'1'、'2'或'3',代码更简洁,JVM的contains方法底层是优化过的字符遍历,比手动取模除法快:
import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; public class Main { public static void take(int[] a) { // 预分配容量,避免ArrayList扩容开销 ArrayList<Integer> ai = new ArrayList<>(a.length); for (int num : a) { // 增强for循环,比普通for更顺手也高效 String numStr = String.valueOf(num); if (numStr.contains("1") || numStr.contains("2") || numStr.contains("3")) { ai.add(num); } } if (ai.isEmpty()) { System.out.println(-1); } else { Collections.sort(ai); System.out.println(ai); } } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int testCases = scanner.nextInt(); for (int i = 0; i < testCases; i++) { int arrSize = scanner.nextInt(); int[] arr = new int[arrSize]; for (int j = 0; j < arrSize; j++) { arr[j] = scanner.nextInt(); } take(arr); } scanner.close(); // 记得关Scanner,别浪费资源 } }
方案2:优化逐位判断(不想转字符串的话)
要是你不想用字符串,那可以把原有的逐位判断逻辑改得更清晰,不碰原数组:
import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; public class Main { public static void take(int[] a) { ArrayList<Integer> ai = new ArrayList<>(a.length); for (int num : a) { int temp = num; boolean hasTargetDigit = false; while (temp > 0) { int digit = temp % 10; if (digit == 1 || digit == 2 || digit == 3) { hasTargetDigit = true; break; // 找到目标数字就立刻跳出循环,别做无用功 } temp /= 10; } if (hasTargetDigit) { ai.add(num); } } if (ai.isEmpty()) { System.out.println(-1); } else { Collections.sort(ai); System.out.println(ai); } } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int testCases = scanner.nextInt(); for (int i = 0; i < testCases; i++) { int arrSize = scanner.nextInt(); int[] arr = new int[arrSize]; for (int j = 0; j < arrSize; j++) { arr[j] = scanner.nextInt(); } take(arr); } scanner.close(); } }
终极优化:处理大规模输入的杀手锏
如果你的测试用例输入特别大,Scanner的速度肯定不够,换成BufferedReader来读输入,速度能提升一大截,这往往是超时的罪魁祸首:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Collections; import java.util.StringTokenizer; public class Main { public static void take(int[] a) { ArrayList<Integer> ai = new ArrayList<>(a.length); for (int num : a) { String numStr = String.valueOf(num); if (numStr.contains("1") || numStr.contains("2") || numStr.contains("3")) { ai.add(num); } } if (ai.isEmpty()) { System.out.println(-1); } else { Collections.sort(ai); System.out.println(ai); } } public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int testCases = Integer.parseInt(br.readLine()); while (testCases-- > 0) { int arrSize = Integer.parseInt(br.readLine()); int[] arr = new int[arrSize]; StringTokenizer st = new StringTokenizer(br.readLine()); for (int j = 0; j < arrSize; j++) { arr[j] = Integer.parseInt(st.nextToken()); } take(arr); } br.close(); } }
这些优化点加起来,应该能帮你把运行时间降到符合要求的范围啦!
内容的提问来源于stack exchange,提问作者user8830835
相关产品推荐
相关产品推荐

