力扣刷题常用方法与 ACM 模式输入输出速查(Python 版)
1. 引言
刷题时经常被一些“平时知道,用的时候忘了”的操作卡住,比如 index、max、pop、reverse,以及 Counter、defaultdict、deque 等。更重要的是,力扣习惯了核心代码模式,面对 ACM 模式的输入输出会手忙脚乱。本文统一以 def main(): ... if __name__ == "__main__": main() 的骨架,整理常用数据类型的方法、collections 高频工具,以及各类输入输出样例,不涉及具体算法,专做基础补全。
2. 常用数据类型与方法速查
这里只列刷题最常用的方法,按可变/不可变、返回值、原地操作分类,避免混淆。
2.1 列表 list
li = [3, 1, 2]
li.append(4) # 末尾追加
li.pop() # 弹出末尾,返回元素
li.pop(1) # 按下标弹出
li.insert(1, 5) # 在下标 1 插入 5
li.remove(3) # 按值删除第一个匹配项
li.index(2) # 返回第一个 2 的下标
li.count(2) # 统计 2 的出现次数
li.sort() # 原地排序,返回 None
li.sort(reverse=True) # 降序
sorted_li = sorted(li) # 返回新列表,不改变原列表
sorted_li = sorted(li, reverse=True)
li.reverse() # 原地反转,返回 None
reversed_li = list(reversed(li))# 返回迭代器,需转列表
max(li) # 最大值
min(li) # 最小值
sum(li) # 求和
len(li) # 长度
all(li) # 全部为 True
any(li) # 任一为 True
# 列表推导式
squares = [x**2 for x in range(10)]
2.2 字符串 str
s = "hello world"
s.split() # ['hello', 'world']
s.split('o') # ['hell', ' w', 'rld']
s.find('w') # 返回第一个下标,未找到返回 -1
s.index('w') # 同上,未找到抛 ValueError
s.count('l') # 统计子串次数
s.replace('world', 'python') # 替换
s.startswith('he') # 是否以 he 开头
s.endswith('ld') # 是否以 ld 结尾
' '.join(['a', 'b', 'c']) # 连接列表元素
s.strip() # 去除首尾空白
s.lstrip() / s.rstrip()
s.isdigit() # 是否为全数字
s.isalpha() # 是否为全字母
s.upper() / s.lower()
s[::-1] # 反转字符串
2.3 字典 dict
d = {'a': 1, 'b': 2}
d['a'] # 取值(键不存在抛 KeyError)
d.get('c', 0) # 安全取值,不存在返回 0
d.keys() / d.values() / d.items()
for k, v in d.items(): ...
d.pop('a') # 弹出键并返回值
d.popitem() # 弹出最后插入的键值对(3.7+ 有序)
d.update({'c': 3}) # 合并字典
del d['b'] # 删除键值对
2.4 集合 set
s = {1, 2, 3}
s.add(4)
s.remove(2) # 元素不存在抛 KeyError
s.discard(5) # 安全删除
s.pop() # 随机弹出
s1 & s2 # 交集
s1 | s2 # 并集
s1 - s2 # 差集
s1 ^ s2 # 对称差集
2.5 栈、队列与堆
栈直接用 list 模拟:append + pop。队列推荐 collections.deque(见第 3 节)。堆使用 heapq:
import heapq
heap = []
heapq.heappush(heap, 3)
heapq.heappush(heap, 1)
val = heapq.heappop(heap) # 弹出最小值
heapq.heapify([3, 1, 2]) # 原地建堆
# 大顶堆可以通过存储负数实现
3. collections 高频工具
3.1 Counter —— 计数器
from collections import Counter
cnt = Counter("abracadabra")
cnt['a'] # 5
cnt.most_common(2) # [('a', 5), ('b', 2)]
cnt.update("aaaa") # 增加计数
cnt.subtract("aa") # 减少计数
3.2 defaultdict —— 带默认值的字典
from collections import defaultdict
d = defaultdict(int) # 默认值 0
d['x'] += 1 # 不需要判断键是否存在
d = defaultdict(list) # 默认空列表
d['y'].append(1)
d = defaultdict(set) # 默认空集合
3.3 deque —— 双端队列
from collections import deque
q = deque([1, 2, 3])
q.append(4) # 右侧入队
q.appendleft(0) # 左侧入队
q.pop() # 右侧出队
q.popleft() # 左侧出队
q.rotate(1) # 右移 1 位
4. ACM 模式输入输出骨架
所有示例统一采用以下模板:
import sys
def main():
pass
if __name__ == "__main__":
main()
使用 sys.stdin.read()/sys.stdin.readline() 处理输入,比 input() 更快,且更适配多行场景。
4.1 单行输入
样例: 3 5 7
def main():
line = sys.stdin.readline().strip()
nums = list(map(int, line.split()))
print(nums) # [3, 5, 7]
4.2 多行输入(已知行数)
样例:
3 # 接下来有 3 行
1 2 3
4 5 6
7 8 9
def main():
n = int(sys.stdin.readline())
matrix = []
for _ in range(n):
row = list(map(int, sys.stdin.readline().split()))
matrix.append(row)
print(matrix)
4.3 无限输入(直到 EOF)
样例:
1 2
3 4
5 6
(EOF)
def main():
for line in sys.stdin:
a, b = map(int, line.split())
# 处理每一行
4.4 多组测试用例(首行给出 T)
样例:
2
3 4
5 5
def main():
data = sys.stdin.read().strip().split()
t = int(data[0])
idx = 1
for _ in range(t):
n = int(data[idx]); idx += 1
m = int(data[idx]); idx += 1
# 处理一组
4.5 单行输入一个列表(带空格)
样例: 1 2 3 4 5
def main():
arr = list(map(int, sys.stdin.readline().split()))
4.6 单行输入一个字符串(可能含空格)
def main():
s = sys.stdin.readline().strip() # 去除末尾换行和空格
若要保留行内空格,用 .rstrip('\n')。力扣输入通常没有多余空格。
4.7 输入多行字符串列表
样例:
abc
def
ghi
def main():
n = int(sys.stdin.readline())
strs = [sys.stdin.readline().strip() for _ in range(n)]
或用无限输入:
def main():
strs = [line.strip() for line in sys.stdin]
5. 常见数据结构的输入输出写法
5.1 链表
力扣核心模式给出链表头节点;ACM 模式通常给一个数组,需要自己构建链表并返回头节点。输出也常需打印链表整个序列。
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def build_linked_list(nums):
"""从列表构建链表,返回头节点"""
dummy = ListNode()
cur = dummy
for num in nums:
cur.next = ListNode(num)
cur = cur.next
return dummy.next
def print_linked_list(head):
"""打印链表(假设节点值用 -> 连接)"""
res = []
while head:
res.append(str(head.val))
head = head.next
print("->".join(res))
def main():
# 样例输入:1 2 3 4
nums = list(map(int, sys.stdin.readline().split()))
head = build_linked_list(nums)
# 调用解题函数
# ...
print_linked_list(head)
5.2 二叉树
ACM 模式通常给层序遍历序列(null/None 表示空节点),需要构建树;输出常为前中后序或层序。
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def build_tree(vals):
"""vals: 列表,None 表示空节点(层序)"""
if not vals:
return None
root = TreeNode(vals[0])
queue = deque([root])
i = 1
while queue and i < len(vals):
node = queue.popleft()
if i < len(vals) and vals[i] is not None:
node.left = TreeNode(vals[i])
queue.append(node.left)
i += 1
if i < len(vals) and vals[i] is not None:
node.right = TreeNode(vals[i])
queue.append(node.right)
i += 1
return root
def main():
line = sys.stdin.readline().strip()
# 输入如 "1,2,3,null,4"
parts = line.replace("null", "None").split(",")
vals = [int(x) if x != "None" else None for x in parts]
root = build_tree(vals)
# ...
5.3 图(邻接表/邻接矩阵)
图常以边列表形式给出,例如第一行 n m 表示节点数、边数,接下来 m 行每行 u v 表示边。
无向图邻接表:
def main():
n, m = map(int, sys.stdin.readline().split())
graph = [[] for _ in range(n)]
for _ in range(m):
u, v = map(int, sys.stdin.readline().split())
graph[u].append(v)
graph[v].append(u)
有向带权图邻接表:
def main():
n, m = map(int, sys.stdin.readline().split())
graph = [[] for _ in range(n)]
for _ in range(m):
u, v, w = map(int, sys.stdin.readline().split())
graph[u].append((v, w))
6. 更复杂的输入样例
6.1 不定个数的一行列表
直接读一行并按空格分割:
def main():
arr = list(map(int, sys.stdin.readline().split()))
6.2 多行不定个数,每行不同格式
def main():
lines = sys.stdin.read().strip().splitlines()
for line in lines:
if not line:
continue
parts = line.split()
# 根据 parts[0] 判断处理方式
6.3 包含字符串和数字混合的行
def main():
tokens = sys.stdin.readline().split()
name = tokens[0]
age = int(tokens[1])
7. 总结
本文整理了 Python 刷题中容易被遗忘的常用方法,以及从简单到复杂的 ACM 输入输出写法,全部以 def main() + if __name__ == "__main__": main() 统一呈现。建议将此文加入收藏,碰到陌生输入或遗忘方法时快速查阅。后续如需补充其他数据结构或技巧,可随时扩充。
更多推荐


所有评论(0)