LeetCode 344简单双指针/字符串
反转字符串 图解题解
这道题到底在问什么
给定字符数组 s,原地反转其中的字符。不能返回新数组,必须在输入数组上修改,额外空间 O(1)。
- 输入
- s=["h","e","l","l","o"]
- 输出
- ["o","l","l","e","h"]
- 输入
- s=["a","b"]
- 输出
- ["b","a"]
最优解:一步一步想明白
- 3记住这套「两端交换、双指针向中间靠拢」,下面每一帧都在套它。
- 4开局:左指针 l 落在第 0 位 d、右指针 r 落在第 12 位 e。只要 l < r 就交换两端,再一起往中间挪。
- 5第 1 次:l 指着 d、r 指着 e,l < r 成立,这两端该互换。
- 6交换完成:e 换到第 0 位、d 换到第 12 位(绿色=已归位),这两个字符之后不用再动。
- 7指针内移:l 右移到 1、r 左移到 11,继续。
- 8第 2 次:l 指着 a、r 指着 r,l < r 成立,这两端该互换。
- 9交换完成:r 换到第 1 位、a 换到第 11 位(绿色=已归位),这两个字符之后不用再动。
- 10指针内移:l 右移到 2、r 左移到 10,继续。
- 11第 3 次:l 指着 t、r 指着 u,l < r 成立,这两端该互换。
- 12交换完成:u 换到第 2 位、t 换到第 10 位(绿色=已归位),这两个字符之后不用再动。
- 13指针内移:l 右移到 3、r 左移到 9,继续。
- 14第 4 次:l 指着 a、r 指着 t,l < r 成立,这两端该互换。
- 15交换完成:t 换到第 3 位、a 换到第 9 位(绿色=已归位),这两个字符之后不用再动。
- 16指针内移:l 右移到 4、r 左移到 8,继续。
- 17第 5 次:l 指着 s、r 指着 c,l < r 成立,这两端该互换。
- 18交换完成:c 换到第 4 位、s 换到第 8 位(绿色=已归位),这两个字符之后不用再动。
- 19指针内移:l 右移到 5、r 左移到 7,继续。
- 20第 6 次:l 指着 t、r 指着 u,l < r 成立,这两端该互换。
- 21交换完成:u 换到第 5 位、t 换到第 7 位(绿色=已归位),这两个字符之后不用再动。
- 22指针内移:l 和 r 在中点 6 相遇,停。
- 23l 和 r 会合,反转完成,整串变成 erutcurtsatad。正中央第 6 位的 r 没有配对,自己留在原地。全程只在原数组上两两对调、没开新数组,空间 O(1)。
⚠️ 容易写错的地方
✗ 错:另开一个新数组倒着拷贝
✓ 对:在原数组上用双指针就地交换
题目明确要求原地、空间 O(1),开新数组不符合要求
✗ 错:循环写成 l <= r
✓ 对:用 l < r
l == r 是同一个位置,再交换是自己跟自己换,多余且无意义
✗ 错:忘了同时移动两个指针
✓ 对:每次交换后 l++ 且 r−−
只动一个指针会原地打转或越界,反转不完整
完整代码(Python / C++ / Java)
Python
from typing import List
class Solution:
def reverseString(self, s: List[str]) -> None:
l, r = 0, len(s) - 1
while l < r:
s[l], s[r] = s[r], s[l]
l += 1
r -= 1C++
#include <algorithm>
#include <vector>
using namespace std;
class Solution {
public:
void reverseString(vector<char>& s) {
int l = 0, r = (int)s.size() - 1;
while (l < r) swap(s[l++], s[r--]);
}
};Java
import java.util.*;
class Solution {
public void reverseString(char[] s) {
int l = 0, r = s.length - 1;
while (l < r) {
char t = s[l];
s[l++] = s[r];
s[r--] = t;
}
}
}复杂度
时间
O(n)
每个字符只被指针碰一次,一共换 n/2 次
空间
O(1)
只用 l、r 两个下标,就地交换不开数组
看不够?换成动画再走一遍
上面的推演每一步都对应一帧动画。点开交互动画版,能一步步看着 反转字符串 的数据怎么变、指针怎么走,还能切 Python / Java / C++ 跟着练。
面试官可能追问
如果是反转「字符串」而不是字符数组,做法一样吗?+
思路一样,但很多语言里字符串不可变(如 Java 的 String、Python 的 str),不能原地改,要先转成字符数组再双指针反转、最后拼回字符串。本题给的是字符数组,所以能直接原地交换。
能不能用语言自带的 reverse 函数?+
能,但面试考的就是你会不会手写双指针。自带 reverse 内部也是同样的对撞交换,理解了这套,按「整段反转」「区间反转」「按单词反转」等变体都能举一反三。
想听吴师兄把这道题讲给你听?
文字版和动画都随便看。开通图解算法年卡,可以听吴师兄声线把 反转字符串 一步步讲透(全站 0 节语音精讲,持续扩充), 卡住的地方还有 AI 私教小欧就着动画帮你拆到懂。
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。