PIO11. 多组 字符串倒置(T 组形式)
题目描述
给定 T 组询问,每次给出一个长度为 n 的字符串 s(仅含小写英文字母), 请你将其倒置后输出。
输入格式
第一行一个整数 T。 随后 T 组数据。每组的第一行有一个整数 n,代表字符串长度。 每组的第二行有一个字符串 s。
输出格式
输出 T 行,每行一个字符串,代表倒置后的 s。
示例
示例 1
输入:
3
5
abcde
8
redocwon
9
tfarcenim
输出:
edcba
nowcoder
minecraft
说明:
abcde 倒置是 edcba;redocwon 倒置是 nowcoder;
tfarcenim 倒置是 minecraft。
解题思路
第一步:理解问题本质
每组给出「长度 n + 字符串 s」,要求把 s 倒置。倒置本身是 O(n) 的操作, 难点只在读输入的节奏。
第二步:n 有什么用
题目给的 n 其实就是 len(s)。它存在的意义是印证输入格式,
不能用来截取字符串(没有额外信息,多此一举)。
读进来后直接对整行字符串做倒置即可。
第三步:用切片倒置(最优)
Python 里倒置字符串最简洁的写法就是切片 s[::-1]:
"abcde"[::-1] # -> "edcba"
[::-1] 表示从末尾到开头、步长为 -1,一次遍历就完成,时间和空间都是 O(n)。
如果要逐字符手动构造,也可以:
"".join(reversed(s))
效果一样,但可读性不如切片。
完整代码实现
算法可视化 · 逐帧回放这道题的代码7 帧 · 录制输入
import sys
def solve() -> None:
"""读取 T 组字符串并倒置输出"""
input = sys.stdin.readline
t_line = input()
if not t_line:
return
t = int(t_line)
out = []
for _ in range(t):
_n = int(input()) # 长度,仅用于读掉这一行
s = input().rstrip("\n") # 字符串本体
out.append(s[::-1])
sys.stdout.write("\n".join(out) + "\n")
if __name__ == "__main__":
solve()
示例推演
以第二组 redocwon 为例:
| 原下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| 原字符 | r | e | d | o | c | w | o | n |
| 新下标 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
结果 nowcoder。
复杂度分析
| 解法 | 时间复杂度 | 空间复杂度 | 说明 |
|---|---|---|---|
切片 [::-1] | O(n) | O(n) | 最简洁,推荐 |
reversed + join | O(n) | O(n) | 可读性一般 |
n 为单个字符串长度;多组时为 Σn。
易错点总结
1. 漏读长度行
每组有两行:先长度、再字符串。如果只读字符串行, 下一组就会把长度当成字符串读进去,整体错位。
2. 把 n 当成有效范围去截取
n 就是 len(s),直接用整行即可,不要画蛇添足。
3. 忘记去掉行尾换行符
input() 返回的行带 \n,倒置前要 rstrip("\n"),
否则换行符会被倒到最前面。
扩展思考
- 如果字符串里可能带空格,就必须用
readline而不是read().split()。 - 判断回文串本质上就是比较
s == s[::-1],是本题的直接应用。