牛客网新手入门130_53-58题_20260105

35 阅读6分钟

前言

最近通过一系列 Java 实战题目,梳理了不少基础知识点和容易踩坑的细节。本文会把这些内容体系化整理,涵盖字符串操作、数据结构、算法入门三大模块,每个模块都搭配「知识点解析 + 错题复盘」,适合 Java 新手查漏补缺,也能作为面试基础复习资料。


一、核心知识点体系梳理

(一)字符串操作(高频考点)

字符串是 Java 开发中最常用的类型,也是笔试面试的基础,以下是实战中必须掌握的核心知识点:

1. 字符串读取

  • Scanner.nextLine() :读取整行输入(包含空格),适合处理带空格的字符串(如复合词、句子)。
  • Scanner.next() :仅读取空格前的内容,适合处理无空格的字符串(如单个单词、数字字符串)。
  • ❗ 关键注意:nextInt()/next() 后调用 nextLine() 会读取残留换行符,需额外调用 nextLine() 吸收。

2. 字符串内容操作

方法作用示例
charAt(int index)获取指定索引的字符(索引从 0 开始)"abc".charAt(0) → 'a'
substring(a, b)截取 [a, b) 区间的子串"hello".substring(1,3) → "el"
replace(c1, c2)替换所有指定字符"114514".replace('5', '') → "11414"
split("分隔符")按分隔符分割字符串为数组"I am Bob".split(" ") → ["I", "am", "Bob"]
toUpperCase()转大写(toLowerCase()转小写)"am".toUpperCase() → "AM"
equals(str)比较字符串内容(区分大小写)"Bob".equals("bob") → false
equalsIgnoreCase(str)忽略大小写比较内容"Bob".equalsIgnoreCase("bob") → true

3. 高效字符串拼接

  • StringBuilder:可变字符串,适合频繁拼接(如循环中拼接字符),核心方法:
    • append(内容):追加字符 / 字符串(效率远高于 String + 拼接);
    • reverse():反转字符串;
    • toString():转为普通 String。
  • 为什么不用 String 直接拼接?String 是不可变对象,每次拼接都会创建新对象,循环中使用效率极低。

(二)基础数据结构

1. 栈(Stack)

  • 核心特性:先进后出(LIFO) ,类比「叠盘子」。
  • 常用方法:push()(入栈)、pop()(出栈)、peek()(查看栈顶)、isEmpty()(判断空)。
  • 应用场景:DFS(深度优先搜索)、括号匹配、逆序输出等。

2. 队列(Queue)

  • 核心特性:先进先出(FIFO) ,类比「排队买票」。
  • 常用方法:offer()(入队)、poll()(出队)、peek()(查看队首)、isEmpty()(判断空)。
  • 应用场景:BFS(广度优先搜索)、任务调度、最短路径问题等。

(三)算法入门

1. DFS(深度优先搜索)

  • 核心思想:一条路走到黑,走不通再回溯(类比「走迷宫选一条路走到头」)。
  • 实现方式:递归(JVM 自动维护调用栈)或手动用栈。
  • 关键步骤:选择当前节点 → 递归深入 → 回溯撤销选择。
  • 适用场景:排列组合、树 / 图遍历、数独求解、N 皇后等。

2. BFS(广度优先搜索)

  • 核心思想:层层扩散,先近后远(类比「往池塘扔石头,水波扩散」)。
  • 实现方式:必须用队列(不能用栈)。
  • 关键步骤:入队初始节点 → 出队当前节点 → 遍历邻接节点入队 → 重复直到队空。
  • 适用场景:最短路径、层级遍历(如二叉树层序遍历)、找最近目标等。

3. 数学逻辑计算

  • 字母循环偏移:(字符 - 'a' + n) % 26 + 'a'(小写字母向后错位 n 位,z 循环到 a)。
  • 数位定位:通过数学计算确定目标位置所在的数字位数(如无限字符串第 n 位字符问题)。

二、高频错题复盘(避坑指南)

错题 1:输入读取残留换行符问题

错误代码

Scanner in = new Scanner(System.in);
int n = in.nextInt();
String s = in.nextLine(); // 错误:读取到的是n后的换行符,s为空

问题原因

nextInt() 仅读取整数,不会吸收输入后的换行符,后续 nextLine() 直接读取该换行符,导致字符串为空。

正确解法

在 nextInt() 后添加 in.nextLine() 吸收换行符:

int n = in.nextInt();
in.nextLine(); // 吸收残留换行符
String s = in.nextLine(); // 正确读取字符串

错题 2:字符串分割边界错误(千分位格式化 / 子串匹配)

错误代码(子串 "Bob" 匹配)

String s = "Bob";
for (int i = 0; i < 3; i++) { // 错误:循环边界少了等号
    String sub = s.substring(i, i+3);
}

问题原因

当字符串 s 的长度为 3 时,若要遍历所有长度为 3 的子串,循环条件 i < len - 3 存在问题。因为当 i 取值到 len - 3 时,才是最后一个合法的子串起始位置,原条件 i < len - 3 会导致循环跳过最后一个子串的匹配。以 s = "Bob" 为例,len = 3,len - 3 = 0,此时 i < len - 3 不成立,循环直接结束,无法匹配到 "Bob" 这个子串 ;正确边界应包含 len - 3,即 i <= len - 3。

正确解法

String s = "Bob";
for (int i = 0; i <= 0; i++) { // 包含最后一个可能的起始位置
    String sub = s.substring(i, i+3);
}

错题 3:用 == 比较字符串内容

错误代码

if (niuNiu == "elephant") { // 错误:比较的是内存地址,不是内容
    // ...
}

问题原因

== 对于对象类型,比较的是内存地址(是否为同一个对象);而字符串内容比较必须用 equals()。

正确解法

if (niuNiu.equals("elephant")) { // 比较内容
    // ...
}
// 避免空指针优化:常量放前面
if ("elephant".equals(niuNiu)) {
    // ...
}

错题 4:字母循环偏移未处理边界(z→a)

错误代码

char now = (char)(origin + n); // 错误:z+1会变成'{',超出字母范围

问题原因

小写字母 ASCII 码范围是 97(a)-122(z),直接加 n 会超出范围,需用取模处理循环。

正确解法

int offset = (origin - 'a' + n) % 26; // 转为0-25后取模
char now = (char)('a' + offset); // 转回小写字母

错题 5:复合词简写时首字母转大写错误

错误代码

char upperChar = firstChar.toUpperCase(); // 错误:char不能直接调用String方法

问题原因

toUpperCase() 是 String 类的方法,char 类型不能直接调用,需先转为 String。

正确解法

String upperChar = String.valueOf(firstChar).toUpperCase();

三、实战题目总结(附核心思路)

题目类型核心思路
字符替换(5→*)直接用 String.replace('5', '*') 高效替换
博弈游戏胜负判断枚举胜负规则,用 equals() 比较棋子类型
千分位格式化字符串从后往前遍历,每 3 位插入逗号,用 StringBuilder 拼接后反转
子串首次出现位置遍历可能的起始位置,substring 截取后匹配(注意循环边界)
字母向后错位加密用 (char - 'a' + n) % 26 + 'a' 处理循环偏移
无限字符串第 n 位字符先定位位数区间(1 位 / 2 位 / 3 位),再计算具体数字和字符位置
复合词简写按空格分割字符串,提取每个单词首字母转大写,拼接结果

四、学习建议

  1. 基础优先:字符串操作、数据结构(栈 / 队列)是 Java 基础中的基础,必须熟练掌握,后续复杂算法都依赖这些知识点;
  1. 错题复盘:把踩过的坑(如换行符、== vs equals)整理成笔记,避免重复犯错;
  1. 实战驱动:通过简单题目巩固知识点(如本文中的实战题),再逐步过渡到复杂算法;
  1. 注重效率:字符串频繁拼接用 StringBuilder,避免不必要的性能损耗。

如果觉得本文对你有帮助,欢迎点赞、收藏~ 后续会持续更新 Java 进阶知识点和算法实战!