LeetCode 195. 第十行
目录
题目描述
✅ 195. 第十行
题意分析
给定文本文件
file.txt,只输出第 10 行。行号从 1 开始;空行同样占据一个行号,因为题目按物理行而不是非空记录计数。文件可能不足 10 行。此时没有第 10 行,正确行为是不输出任何内容,不能退而输出最后一行,也不需要输出错误提示。
一旦读到并打印第 10 行,后续内容与答案无关,可以立即退出。相比只写
sed -n '10p'后继续扫描到文件末尾,提前终止在大文件中更符合流式处理思路。官方样例包含
Line 1到Line 10,结果只应出现一行Line 10,不能夹带其它行或调试信息。
解法一:sed 按地址打印并退出
核心思路
sed -n关闭默认的逐行输出。地址10只让花括号中的命令作用于第 10 行:p打印当前行,q随即退出。如果文件提前结束,地址
10永远不会命中,p和q都不会执行,且由于-n已关闭默认输出,最终自然为空。
解题步骤
- 使用
-n禁止sed默认打印每一行。- 在第 10 行执行
p,只打印目标行。- 紧接着执行
q,避免继续读取无关的后续内容。
代码实现
sed -n '10{p;q;}' file.txt
复杂度分析
设从文件开头到第 10 行末尾(若不足 10 行则到 EOF)的字符数为 $K$,最长单行长度为 $L$。
- 时间复杂度:$O(K)$,最多扫描到第 10 行即退出;若文件不足 10 行,则扫描整个文件。
- 空间复杂度:$O(L)$,
sed只需保存当前模式空间,相对整个文件是流式常量空间。
关键点总结
-n和p必须配套:前者关闭默认输出,后者只打印目标行。q要和地址10放在同一个命令块中,否则可能在第一行就退出。- 行数不足时应零输出,这一点使
head | tail的直观组合存在陷阱。- 目标行一旦找到就可以结束,体现 Shell 流式命令的短路意识。
解法二:awk 使用内建行号
核心思路
awk的NR是从输入开始累计的记录号。文本默认一行一条记录,所以在NR == 10时打印当前记录并exit,语义与sed完全一致。
代码实现
awk 'NR == 10 { print; exit }' file.txt
复杂度分析
- 时间复杂度:$O(K)$,读取到第 10 行或 EOF。
- 空间复杂度:$O(L)$,只缓冲当前记录。
解法对比
| 写法 | 优点 | 注意点 |
|---|---|---|
sed -n '10{p;q;}' |
最贴合“按地址选择一行”,命令短 | 需要同时理解 -n、p、q
|
awk 'NR == 10 { print; exit }' |
条件语义直观,容易扩展成复杂行过滤 |
== 不能误写成赋值 |
易错点总结
- 使用
head -n 10 file.txt | tail -n 1:当文件只有 6 行时,它会输出第 6 行,而正确答案应为空。若使用该思路还必须先确认确有 10 行。- 写成
sed '10p'而没有-n:sed会默认输出全部行,并把第 10 行额外再打印一次。- 写成
sed -n '10p;q':不带地址约束的q会在处理第一行后退出,永远到不了第 10 行;应使用10{p;q;}。- 使用
tail -n +10:它会从第 10 行一直输出到文件末尾,而不是只输出一行。- 先过滤空行再计数:题目按原文件物理行号计算,删除空行会让后续行号整体前移。
- 忘记提前退出:
sed -n '10p'虽然答案正确,但仍会扫描超大文件的全部剩余内容;面试追问性能时应补上q或exit。
相似题目
| 题目 | 难度 | 考察点 |
|---|---|---|
| 192. 统计词频 | 中等 | 多级管道处理全部文本并统计聚合 |
| 193. 有效电话号码 | 简单 | 用完整行正则筛选目标记录 |
| 194. 转置文件 | 中等 | 必须缓存字段并在 EOF 后重排输出 |