【算法】吃透18种Java 算法快速读写模板

链接:https://www.nowcoder.com/exam/oj?page=1&tab=%E7%AE%97%E6%B3%95%E7%AC%94%E9%9D%A2%E8%AF%95%E7%AF%87&topicId=372

前言

为什么普通的 Scanner 会超时?

我们平时写练习常用 Scanner sc = new Scanner(System.in),但在笔试 / 算法题中 90% 会超时

原因:

  1. **Scanner** 效率极低:底层同步、解析慢,面对大量输入数据直接超时。
  2. 换行、空格处理弱:连续空格、空行、多行输入容易读错。
  3. 大数据量下性能差距巨大BufferedReaderScanner5~10 倍

所以:只要是笔试 / 算法题,一律使用「快读模板」

  • 避免超时 :笔试时间限制严格,Scanner 必挂。
  • 格式稳定:自动处理多空格、空行、多行输入。
  • 不越界StringTokenizer 不会像 split() 那样切出空数组。
  • 通用万能:一套模板走所有题型(整数、小数、字符串、多行、多组数据)。

快读三个核心类

BufferedReader(缓冲字符输入流)

  • 作用 :带缓冲区的高效读取,一次性读一大块数据,而不是一个字符一个字符读。
  • 核心方法readLine() ------ 读取一整行字符串。
  • 优势:速度极快,是 Java 最快的读取方式之一。

StringTokenizer(字符串分词器)

  • 作用 :把一行字符串按空格 / 换行 / 制表符自动切割成一个个单词(token)。

  • 核心方法

    • hasMoreTokens():是否还有下一个单词
    • nextToken():取下一个单词
  • 优势 :✅ 自动处理任意多个连续空格 ✅ 自动处理换行错乱 ✅ 不会数组越界✅ 比 split() 更快更稳

PrintWriter(缓冲打印输出流)

  • 作用 :比 System.out.println 更快的输出方式,带缓冲。
  • 核心方法print() / println() / printf() / flush()
  • 优势:大量输出时不卡顿,不超时。
java 复制代码
import java.io.*;
import java.util.*;

// 万能快读模板
public class Main {
    public static void main(String[] args) throws IOException {
        // 快读
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        // 快写
        PrintWriter out = new PrintWriter(System.out);
        // 分词器(自动切分空格/换行)
        StringTokenizer st = new StringTokenizer(br.readLine());

        // ===================== 下面写你的代码 ======================

        // 示例:读取一个整数
        int n = Integer.parseInt(st.nextToken());
        out.println(n);

        // ==========================================================

        out.flush(); //刷新缓存区,输出
        br.close();  //关闭流
        out.close();
    }
}

常见模式

直接输出

java 复制代码
import java.util.*;
import java.io.*;

public class Main {

    public static void main(String[] args)throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out=new PrintWriter(System.out);
        out.print("Hello Nowcoder!");
        out.flush();
    } 
}

a+b

java 复制代码
import java.util.*;
import java.io.*;

public class Main {

    public static void main(String[] args)throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out=new PrintWriter(System.out);
        StringTokenizer st=new StringTokenizer(br.readLine());

        int a=Integer.parseInt(st.nextToken());
        int b=Integer.parseInt(st.nextToken());
        out.print(a+b);
        out.flush();
    } 
}

多组_A+B_T组形式

java 复制代码
import java.util.*;
import java.io.*;

public class Main {

    public static void main(String[] args)throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out=new PrintWriter(System.out);
        //这里只有一个n,直接读就行
        int n=Integer.parseInt((br.readLine()));
        while(n-->0){
            StringTokenizer st=new StringTokenizer(br.readLine());
            int a=Integer.parseInt(st.nextToken());
            int b=Integer.parseInt(st.nextToken());
            out.println(a+b);
        }
        out.flush();
    } 
}

多组_A+B_EOF

java 复制代码
import java.util.*;
import java.io.*;

public class Main {

    public static void main(String[] args)throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out=new PrintWriter(System.out);
        // StringTokenizer st=new StringTokenizer(br.readLine());

        String line;
        while((line=br.readLine())!=null){
            // line=line.trim();//去掉这一行前后的空格、换行、空白
            // String[] s=line.split("\\s+"); //按"任意空白"分割成字符数组
            String[] s=line.split(" "); //分割
            int a=Integer.parseInt(s[0]);
            int b=Integer.parseInt(s[1]);
            out.println(a+b);
        }
        
        out.flush();
    } 
}

也可以不分割

java 复制代码
String line;
while ((line = br.readLine()) != null) {
    StringTokenizer st = new StringTokenizer(line);
    int a = Integer.parseInt(st.nextToken());
    int b = Integer.parseInt(st.nextToken());
    System.out.println(a + b);
}

多组_A+B_零尾模式

java 复制代码
import java.util.*;
import java.io.*;

public class Main {

    public static void main(String[] args)throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out=new PrintWriter(System.out);
        // StringTokenizer st=new StringTokenizer(br.readLine());

        String line;
        while((line=br.readLine())!=null){
            // line=line.trim();//去掉这一行前后的空格、换行、空白
            // String[] s=line.split("\\s+"); //按"任意空白"分割成字符数组
            String[] s=line.split(" "); //分割
            int a=Integer.parseInt(s[0]);
            int b=Integer.parseInt(s[1]);
            if(a==0&&b==0) break;
            out.println(a+b);
        }
        
        out.flush();
    } 
}

数组

单组_一维数组

java 复制代码
import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out=new PrintWriter(System.out);
        int n = Integer.parseInt(br.readLine()); // 读第一行 n
        StringTokenizer st = new StringTokenizer(br.readLine()); // 读第二行数组
        long sum = 0;
        for (int i = 0; i < n; i++) {
            sum += Long.parseLong(st.nextToken());
        }
        out.println(sum);
        out.flush();
        br.close();
    }
}

多组_一维数组_T组形式

java 复制代码
import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out=new PrintWriter(System.out);
        int t = Integer.parseInt(br.readLine()); // 读第一行 n
        while(t-->0){
            int n = Integer.parseInt(br.readLine()); // 读第一行 n
        StringTokenizer st = new StringTokenizer(br.readLine()); 
            long sum = 0;
            for (int i = 0; i < n; i++) {
                sum += Long.parseLong(st.nextToken());
            }
            System.out.println(sum);
        }
        out.flush();
        br.close();
    }
}

单组_二维数组

java 复制代码
import java.util.*;
import java.io.*;

public class Main {

    public static void main(String[] args)throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out=new PrintWriter(System.out);
        StringTokenizer st=new StringTokenizer(br.readLine());

        int n=Integer.parseInt(st.nextToken());
        int m=Integer.parseInt(st.nextToken());
        long sum=0;
        for(int i=0;i<n;i++){
            st=new StringTokenizer(br.readLine()); //输入一行
            for(int j=0;j<m;j++){
                sum+=Long.parseLong(st.nextToken());
            }
        }
        out.print(sum);
        out.flush();
        br.close();
    } 
}

多组_二维数组_T组形式

java 复制代码
import java.util.*;
import java.io.*;

public class Main {

    public static void main(String[] args)throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out=new PrintWriter(System.out);
        int t=Integer.parseInt(br.readLine());
        while(t-->0){
            StringTokenizer st=new StringTokenizer(br.readLine());
            int n=Integer.parseInt(st.nextToken());
            int m=Integer.parseInt(st.nextToken());
            long sum=0;
            for(int i=0;i<n;i++){
                st=new StringTokenizer(br.readLine()); //输入一行
                for(int j=0;j<m;j++){
                    sum+=Long.parseLong(st.nextToken());
                }
            }
            out.println(sum);
        }
       
        out.flush();
        br.close();
    } 
}

字符串

单组_字符串

  • 加反转
java 复制代码
import java.util.*;
import java.io.*;

public class Main {

    public static void main(String[] args)throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out=new PrintWriter(System.out);
        int t=Integer.parseInt(br.readLine());
        String s = br.readLine();
        String s2=new StringBuilder(s).reverse().toString();
        out.print(s2);
        out.flush();
        br.close();
    } 
}

多组_字符串_T组形式

java 复制代码
import java.util.*;
import java.io.*;

public class Main {

    public static void main(String[] args)throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out=new PrintWriter(System.out);
        int t=Integer.parseInt(br.readLine());
        while(t-->0){
            int n=Integer.parseInt(br.readLine());
            String s = br.readLine();
            String s2=new StringBuilder(s).reverse().toString();
            out.println(s2);
        }

        out.flush();
        br.close();
    } 
}

单组_二维字符数组

比较麻烦,参考一下

java 复制代码
import java.util.*;
import java.io.*;

public class Main {

    public static void main(String[] args)throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out=new PrintWriter(System.out);
        StringTokenizer st=new StringTokenizer(br.readLine());
        int n=Integer.parseInt(st.nextToken());
        int m=Integer.parseInt(st.nextToken());

        char[][] arr=new char[n][m];
        for(int i=0;i<n;i++){
            arr[i]=br.readLine().toCharArray();
        }
        //倒置行顺序
        for(int i=0;i<n/2;i++){
            char[] tmp=arr[i];
            arr[i]=arr[n-1-i];
            arr[n-1-i]=tmp;
        }
        // 再倒置每行
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m / 2; j++) {
                char tmp = arr[i][j];
                arr[i][j] = arr[i][m - 1 - j];
                arr[i][m - 1 - j] = tmp;
            }
        }
        for(int i=0;i<n;i++){
            out.println(new String(arr[i]));
        }
        out.flush();
        br.close();
    } 
}

多组_带空格的字符串_T组形式

java 复制代码
import java.util.*;
import java.io.*;

public class Main {

    public static void main(String[] args)throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out=new PrintWriter(System.out);
        int t=Integer.parseInt(br.readLine());
        while(t-->0){
            int n=Integer.parseInt(br.readLine());
            String[] s = br.readLine().split("\\s+");
            
            StringBuilder ss=new StringBuilder();
            for(int i=s.length-1;i>=0;i--){
                ss.append(new StringBuilder(s[i]).reverse());
            }
            out.println(ss.toString());
           
        }

        out.flush();
        br.close();
    } 
}

格式和简单判断

单组_保留小数位数

给定一个小数 nn ,请你保留 33 位小数后输出。

如果原来的小数位数少于 33 ,需要补充 00 。

如果原来的小数位数多于 33 ,需要四舍五入到 33 位。

java 复制代码
import java.util.*;
import java.io.*;

public class Main {

    public static void main(String[] args)throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out=new PrintWriter(System.out);
        //这里只有一个n,直接读就行
        double n=Double.parseDouble((br.readLine()));
        out.printf("%.3f",n);
        out.flush();
        br.close();
    } 
}

单组_补充前导零

描述

给定一个正整数 nn ,请你保留 99 个数位,然后输出。

如果数位少于 99 个,那么需要补充前导零。

输入描述:

第一行有一个整数 n ( 1≤n<10的9次 ) 。

输出描述:

输出一个数字,保留 9个数位。

比如:

输入:123

输出:000000123

java 复制代码
import java.util.*;
import java.io.*;

public class Main {

    public static void main(String[] args)throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out=new PrintWriter(System.out);
        //这里只有一个n,直接读就行
        int n=Integer.parseInt((br.readLine()));
        out.printf("%09d",n);
        out.flush();
        br.close();
    } 
}

单组_spj判断YES与NO

java 复制代码
import java.io.*;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(System.out);
        
        int n = Integer.parseInt(br.readLine());
        
        // 判断奇偶
        if (n % 2 == 1) {
            out.println("YES");
        } else {
            out.println("NO");
        }
        
        out.flush();
        br.close();
    }
}
相关推荐
2301_816651221 小时前
C++模块化设计原则
开发语言·c++·算法
Ulyanov1 小时前
Python GUI工程化实战:从tkinter/ttk到可复用的现代化组件架构
开发语言·python·架构·gui·tkinter
空空潍1 小时前
Spring AI 实战系列(三):多模型共存+双版本流式输出
java·人工智能·spring
gaozhiyong08131 小时前
提示词的解剖学:Gemini 3.1 Pro 提示工程高级策略与国内实战
人工智能·算法·机器学习
Langchain1 小时前
2026 年 AI 最值得关注的方向:上下文工程!
人工智能·python·自然语言处理·llm·agent·大模型开发·rag
pupudawang2 小时前
Spring EL 表达式的简单介绍和使用
java·后端·spring
jiankeljx2 小时前
Spring Initializr创建springboot项目,提示java 错误 无效的源发行版:16
java·spring boot·spring
小范自学编程2 小时前
算法训练营Day44 - 动态规划part12
算法·动态规划
。。,……~2 小时前
RGB-IR融合算法CDDFUSE理解+复现
算法