Article / 文章
LeetCode 第344题:反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
📖 文章摘要
本文详细解析LeetCode第344题“反转字符串”,这是一道简单难度的字符串操作题目。文章提供了双指针和递归两种解法,包含C#、Python、C++三种语言实现,配有详细的算法分析和性能对比。适合初学算法的程序员学习字符串操作。
核心知识点: 双指针、字符串、原地算法
难度等级: 简单
推荐人群: 初学算法的程序员,想要掌握基本字符串操作的开发者
题目描述
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例
示例 1:
输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]
示例 2:
输入:s = ["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]
提示
- 1 <= s.length <= 105
- s[i] 都是 ASCII 码表中的可打印字符
解题思路
方法一:双指针
使用双指针从两端向中间移动,交换字符。
关键点:
- 左右指针分别从两端开始
- 交换两个指针指向的字符
- 指针向中间移动
- 当左指针大于等于右指针时停止
具体步骤:
- 初始化左指针left = 0,右指针right = length - 1
- 当left < right时循环
- 交换s[left]和s[right]的值
- left++,right–
时间复杂度:O(n) 空间复杂度:O(1)
方法二:递归
使用递归方式从两端向中间交换字符。
关键点:
- 递归的基本情况是左指针大于等于右指针
- 每次递归交换两端字符
- 递归调用处理剩余部分
图解思路
双指针过程分析表
| 步骤 | 数组状态 | left | right | 操作 |
|---|---|---|---|---|
| 初始 | [“h”,“e”,“l”,“l”,“o”] | 0 | 4 | 交换h和o |
| 第1步 | [“o”,“e”,“l”,“l”,“h”] | 1 | 3 | 交换e和l |
| 第2步 | [“o”,“l”,“l”,“e”,“h”] | 2 | 2 | 结束 |
递归过程分析
输入:["h","e","l","l","o"]
递归过程:
1. 交换h和o:["o","e","l","l","h"]
2. 递归剩余部分:
2.1 交换e和l:["o","l","l","e","h"]
2.2 递归中间的l:不需要交换
结果:["o","l","l","e","h"]
代码实现
C# 实现
public class Solution {
// 方法一:双指针
public void ReverseString(char[] s) {
int left = 0, right = s.Length - 1;
while (left < right) {
// 交换字符
char temp = s[left];
s[left] = s[right];
s[right] = temp;
// 移动指针
left++;
right--;
}
}
// 方法二:递归
public void ReverseStringRecursive(char[] s) {
ReverseStringHelper(s, 0, s.Length - 1);
}
private void ReverseStringHelper(char[] s, int left, int right) {
if (left >= right) return;
// 交换字符
char temp = s[left];
s[left] = s[right];
s[right] = temp;
// 递归处理剩余部分
ReverseStringHelper(s, left + 1, right - 1);
}
}
Python 实现
class Solution:
# 方法一:双指针
def reverseString(self, s: List[str]) -> None:
left, right = 0, len(s) - 1
while left < right:
# Python的优雅交换
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
# 方法二:递归
def reverseStringRecursive(self, s: List[str]) -> None:
def helper(left: int, right: int) -> None:
if left >= right:
return
# 交换字符
s[left], s[right] = s[right], s[left]
# 递归处理剩余部分
helper(left + 1, right - 1)
helper(0, len(s) - 1)
C++ 实现
class Solution {
public:
// 方法一:双指针
void reverseString(vector<char>& s) {
int left = 0, right = s.size() - 1;
while (left < right) {
// 交换字符
swap(s[left], s[right]);
left++;
right--;
}
}
// 方法二:递归
void reverseStringRecursive(vector<char>& s) {
reverseStringHelper(s, 0, s.size() - 1);
}
private:
void reverseStringHelper(vector<char>& s, int left, int right) {
if (left >= right) return;
// 交换字符
swap(s[left], s[right]);
// 递归处理剩余部分
reverseStringHelper(s, left + 1, right - 1);
}
};
执行结果
C# 实现
- 执行用时:248 ms
- 内存消耗:46.2 MB
Python 实现
- 执行用时:188 ms
- 内存消耗:21.3 MB
C++ 实现
- 执行用时:16 ms
- 内存消耗:23.1 MB
性能对比
| 语言 | 执行用时 | 内存消耗 | 特点 |
|---|---|---|---|
| C# | 248 ms | 46.2 MB | 代码结构清晰 |
| Python | 188 ms | 21.3 MB | 语法简洁 |
| C++ | 16 ms | 23.1 MB | 性能最优 |
代码亮点
- 🎯 双指针实现简单高效
- 💡 递归实现优雅
- 🔍 原地修改节省空间
- 🎨 代码可读性强
常见错误分析
- 🚫 使用额外数组存储
- 🚫 指针边界处理错误
- 🚫 递归终止条件错误
- 🚫 字符交换逻辑错误
解法对比
| 解法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
|---|---|---|---|---|
| 双指针 | O(n) | O(1) | 简单直观 | 无 |
| 递归 | O(n) | O(n) | 代码优雅 | 空间开销大 |
相关题目
📖 系列导航
🔥 算法专题合集 - 查看完整合集
📢 关注合集更新:点击上方合集链接,关注获取最新题解!目前已更新至第344题。
💬 互动交流
感谢大家耐心阅读到这里!希望这篇题解能够帮助你更好地理解和掌握这道算法题。
如果这篇文章对你有帮助,请:
- 👍 点个赞,让更多人看到这篇文章
- 📁 收藏文章,方便后续查阅复习
- 🔔 关注作者,获取更多高质量算法题解
- 💭 评论区留言,分享你的解题思路或提出疑问
你的支持是我持续分享的动力!
💡 一起进步:算法学习路上不孤单,欢迎一起交流学习!