文章目录
ACM输入 Scanner
import java.util.Scanner;
public class ScannerDemo {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
// 从键盘接收数据
// next方式接收字符串
System.out.println("next方式接收:");
// 判断是否还有输入
if (scan.hasNext()) {
String str1 = scan.next();
System.out.println("输入的数据为:" + str1);
}
scan.close();
}
}
$ javac ScannerDemo.java
$ java ScannerDemo
next方式接收:
runoob com
输入的数据为:runoob
可以看到 com 字符串并未输出
使用 nextLine 方法:
// 判断是否还有输入
if (scan.hasNextLine()) {
String str2 = scan.nextLine();
System.out.println("输入的数据为:" + str2);
}
runoob com
输入的数据为:runoob com
如果要输入 int 或 float 类型的数据,在 Scanner 类中也有支持,但是在输入之前最好先使用 hasNextXxx() 方法进行验证,再使用 nextXxx() 来读取。
以下是针对ACM模式刷题时,字符串和集合相关的高频Java API总结(按使用频率排序):
一、字符串高频API
- String类
String str = "abc";
// 基础操作
str.length() // 字符串长度
str.charAt(int index) // 获取字符(高频)
str.substring(int start) // 截取子串(含start)
str.substring(int start, int end) // 截取[start,end)
str.split(String regex) // 分割字符串(高频,如处理输入)
str.toCharArray() // 转字符数组(高频用于遍历)
str.equals(String other) // 比较内容(非地址)
str.indexOf(String s) // 查找子串位置
// 类型转换
Integer.parseInt(str) // 字符串转整数(高频)
String.valueOf(int/double...) // 其他类型转字符串(高频)
str.toLowerCase() / toUpperCase() // 大小写转换
// 其他
str.trim() // 去除首尾空格
str.replace(old, new) // 替换字符/字符串
str.contains(String s) // 是否包含子串
- StringBuilder(高频!线程不安全但更快)
StringBuilder sb = new StringBuilder();
sb.append("a") // 追加内容(高频)
sb.insert(index, "x") // 插入
sb.delete(start, end) // 删除
sb.reverse() // 反转(高频用于回文题)
sb.toString() // 转String(最终输出)
- Character
Character.isLetter()
Character.toLowerCase()
二、集合高频API
- List(ArrayList最常用)
List<Integer> list = new ArrayList<>();
// 基础操作
list.add(element) // 添加元素(高频)
list.get(int index) // 获取元素(高频)
list.size() // 元素个数(高频)
list.remove(int index) // 按索引删除
list.remove(Object o) // 按对象删除
list.contains(Object o) // 是否包含元素
list.isEmpty() // 判空
// 工具方法
Collections.sort(list) // 排序(高频)
Collections.reverse(list) // 反转
Collections.max(list) / min(list) // 最大/最小值
Collections.fill(list, val) // 填充
// 数组互转
Arrays.asList(T... a) // 数组转List(注意返回固定大小List)
list.toArray(new T[0]) // List转数组
- Map(HashMap最常用)
Map<K, V> map = new HashMap<>();
// 基础操作
map.put(key, value) // 添加/覆盖键值对(高频)
map.get(key) // 获取值(高频)
map.containsKey(key) // 是否包含键(高频)
map.getOrDefault(key, defaultValue) // 安全获取
map.remove(key) // 删除键
map.size() // 键值对数量
// 遍历(高频)
for (Map.Entry<K, V> entry : map.entrySet())
//PriorityQueue(优先队列)
PriorityQueue<Map.Entry<Character, Integer>> pq = new PriorityQueue<>(
(a, b) -> b.getValue() - a.getValue()
);
pq.addAll(map.entrySet());
以下是栈(Stack)和链表(LinkedList)在ACM模式刷题时的高频Java API总结,包含核心操作和避坑指南:
三、栈(Stack)高频API
1. 推荐用Deque
替代Stack
类(更高效且线程不安全,适合算法场景)
Deque<Integer> stack = new ArrayDeque<>();
2. 核心操作
方法 | 说明 | 示例 |
---|---|---|
push(e) |
入栈 | stack.push(5); |
pop() |
出栈(空栈会抛异常) | int top = stack.pop(); |
peek() |
查看栈顶元素(不删除) | int top = stack.peek(); |
isEmpty() |
判断栈是否为空 | if (stack.isEmpty()) {...} |
size() |
获取元素个数 | int len = stack.size(); |
3. 经典应用场景
- 括号匹配:用栈存储左括号,遇到右括号时弹栈匹配
- 单调栈:维护栈内元素单调性(递增/递减)
- 表达式求值:处理运算符优先级
4. 避坑指南
- 空栈检查:
pop()
和peek()
前必须检查栈是否为空,否则会抛出NoSuchElementException
- 性能对比:优先用
ArrayDeque
而非Stack
类(后者同步操作性能差)
四、链表(LinkedList)高频API
1. 内置LinkedList
类
LinkedList<Integer> list = new LinkedList<>();
2. 核心操作
方法 | 说明 | 时间复杂度 |
---|---|---|
addFirst(e) |
头部插入元素 | O(1) |
addLast(e) |
尾部插入元素 | O(1) |
removeFirst() |
删除头部元素(空链表抛异常) | O(1) |
removeLast() |
删除尾部元素(空链表抛异常) | O(1) |
getFirst() |
获取头部元素(不删除) | O(1) |
getLast() |
获取尾部元素(不删除) | O(1) |
get(int index) |
获取第index个元素(低效,慎用) | O(n) |
size() |
获取链表长度 | O(1) |
3. 自定义链表节点(LeetCode常用)
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
// 操作示例:反转链表
ListNode dummy = new ListNode(-1);
while (head != null) {
ListNode next = head.next;
head.next = dummy.next;
dummy.next = head;
head = next;
}
return dummy.next;
4. 经典应用场景
- 链表反转:迭代或递归修改指针指向
- 合并有序链表:双指针遍历比较
- 快慢指针:检测环、找中点(如判断回文链表)
- 虚拟头节点:简化头节点边界处理
5. 避坑指南
- 指针丢失:修改链表节点指针时,注意提前保存
next
节点 - 循环引用:操作链表后注意检查是否成环
- 性能陷阱:避免频繁调用
get(index)
(链表随机访问是O(n))
五、实用代码片段
1. 用栈实现队列
class MyQueue {
Deque<Integer> inStack = new ArrayDeque<>();
Deque<Integer> outStack = new ArrayDeque<>();
public void push(int x) {
inStack.push(x);
}
public int pop() {
if (outStack.isEmpty()) {
while (!inStack.isEmpty()) {
outStack.push(inStack.pop());
}
}
return outStack.pop();
}
}
2. 快慢指针找链表中点
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next; // 慢指针走1步
fast = fast.next.next; // 快指针走2步
}
// slow即为中点(偶数个节点时靠左)
掌握这些API和技巧后,可以高效解决栈和链表相关的算法题,注意边界条件和指针操作的细节!