记录一种 Java 自定义快速读的方式,解决牛客中运行超时问题
针对牛客中 “dd爱框框” 这道题的运行超时问题,分享一种 Java 自定义快速读的方式以解决该问题。题目链接:dd爱框框
题目描述如下:
解题思路:对于本题首先想到的就是双指针思想,一个指针记录左边界,另一个指针遍历数组,期间统计遍历过的和 sum,当 sum 的值大于等于 x 时,右移记录左边界的指针,期间不断更新最小长度区间和指针位置。最终遍历完数组后得到最小长度区间的起点和最小区间长度,通过这两个变量即可输出结果。但注意的是题目要求中第一个数字位置为 1,而我们数组中第一个数字下标为 0,因此需要给 起点 和 起点+最小区间长度 都加上 1,即得到最终的结果。
具体代码如下所示:
import java.util.*;
import java.io.*;
public class Main {public static void main(String[] args) throws IOException {
// Read read = new Read();Scanner read = new Scanner(System.in);int n = read.nextInt();int x = read.nextInt();int[] arr = new int[n];for (int i = 0; i < n; i++) {arr[i] = read.nextInt();}int sum = 0;int left = -1;int index = 0;int length = Integer.MAX_VALUE;for (int i = 0; i < n; i++) {sum += arr[i];while (sum >= x) {if (i - index < length) {left = index;length = i - index;}sum -= arr[index];index++;}}System.out.println((left + 1) + " " + (left + length + 1));}
}
经过反复分析,思路以及写法都没有问题,但在牛客中提交只能通过 20% 的用例,如下图所示。最终发现是输入方式的问题,因此学习了一种 JAVA 的快速读方式,做一个记录。
快速读的 Read 类定义如下:
import java.util.*;
import java.io.*;
class Read {StringTokenizer st = new StringTokenizer("");BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));String next() throws IOException {while (!st.hasMoreTokens()) {st = new StringTokenizer(bf.readLine());}return st.nextToken();}String nextLine() throws IOException {return bf.readLine();}int nextInt() throws IOException {return Integer.parseInt(next());}long nextLong() throws IOException {return Long.parseLong(next());}double nextDouble() throws IOException {return Double.parseDouble(next());}
}
通过在主方法中 new 上述定义的 Read 类来进行数据的读取以替代 Scanner,更换方式后通过了该题,完整代码如下所示:
import java.util.*;
import java.io.*;
public class Main {public static void main(String[] args) throws IOException {Read read = new Read();
// Scanner read = new Scanner(System.in);int n = read.nextInt();int x = read.nextInt();int[] arr = new int[n];for (int i = 0; i < n; i++) {arr[i] = read.nextInt();}int sum = 0;int left = -1;int index = 0;int length = Integer.MAX_VALUE;for (int i = 0; i < n; i++) {sum += arr[i];while (sum >= x) {if (i - index < length) {left = index;length = i - index;}sum -= arr[index];index++;}}System.out.println((left + 1) + " " + (left + length + 1));}
}
class Read {StringTokenizer st = new StringTokenizer("");BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));String next() throws IOException {while (!st.hasMoreTokens()) {st = new StringTokenizer(bf.readLine());}return st.nextToken();}String nextLine() throws IOException {return bf.readLine();}int nextInt() throws IOException {return Integer.parseInt(next());}long nextLong() throws IOException {return Long.parseLong(next());}double nextDouble() throws IOException {return Double.parseDouble(next());}
}