跳转至

BM91 反转字符串

入门通过率 65.92%python3核心代码模式样例通过牛客 AC字符串双指针

牛客原题  源码

讲解章节:字符串处理

一句话

返回逆序的新串,切片 str[::-1] 一步到位。

解题思路

这题考什么

签名要求「返回反转后的字符串」而不是原地反转——Python 的 str 不可变, 想原地改也做不到,必然要造一个新对象。反转本身只是一次下标映射, 新串第 i 位取原串第 n-1-i 位:

"abcd"  ->  "dcba"
 ^  ^        依次取下标 n-1, n-2, ..., 0

s[::-1] 是「起点终点都省略、步长 -1」的切片,表示整串倒着走一遍, 由解释器在 C 层一次拷贝完成,比任何 Python 层的循环都快。 等价的手写版本是双指针交换:

chars = list(s)
l, r = 0, len(chars) - 1
while l < r:
    chars[l], chars[r] = chars[r], chars[l]
    l += 1
    r -= 1
return "".join(chars)

在 C 或 Java 那种字符数组可变的语言里,上面这段就是标准的 O(1) 额外空间解法; Python 因为要先 list(s) 展开、再 join 收回,反而比切片多用一份内存。

数据规模与复杂度

n <= 1000,时限「其他语言 2 秒」,题面要求时间 O(n)、空间 O(n)。 切片一次拷贝,时间 O(n)、空间 O(n)(结果串本身)。 这个规模下写法再糟也能过,但「逐字符 res = c + res 前插」是 O(n^2): 字符串不可变,每次前插都重新分配并拷贝整串,值得从一开始就避开。

坑在哪

  1. 切片的三个位置是 [起点 : 终点 : 步长],反转必须把前两个都留空。 省略号的默认值随步长符号而变:步长为负时起点默认是末位、终点默认是「首位之前」。 写成 s[0:len(s):-1] 会得到空串,因为步长为负时要求起点在终点右边。
  2. 空串反转还是空串,切片天然处理(题面允许 n = 0),不必特判。
  3. 参数名 str 遮蔽了内置的 str 类型,这是牛客模板自带的,签名不能改; 实现里因此不能再用 str(...) 做类型转换。

参考实现

solutions/nowcoder/BM91/sol.py
1
2
3
4
5
6
7
from typing import List, Optional


class Solution:
    def solve(self, str: str) -> str:
        # 起点与终点都省略、步长 -1:整串倒着走一遍,一次拷贝出新串
        return str[::-1]
[:octicons-arrow-left-16: BM90](BM90.md) [BM92 :octicons-arrow-right-16:](BM92.md)