34.字符串反转
一、问题描述
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[]
的形式给出。 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
示例:
plaintext
输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]
二、方案一:双指针法
1、思路
双指针法是一种简单而高效的方法。我们设置两个指针,一个指向数组的开始,另一个指向数组的末尾。然后交换这两个位置的字符,并将两个指针向中间移动,重复此过程直到两个指针相遇。
2、代码实现
go
func reverseString(s []byte) {
left, right := 0, len(s)-1
for left < right {
// 交换两个指针指向的字符
s[left], s[right] = s[right], s[left]
// 移动指针
left++
right--
}
}
3、复杂度分析
- 时间复杂度:O(n),其中 n 是字符串的长度。我们只需要遍历一半的字符。
- 空间复杂度:O(1),我们只需要常数级别的额外空间。
三、方案三:递归法
1、思路
每次只交换首尾两个字符,递归进行,直到交换所有字符串
2、代码实现
go
func reverseString(s []byte) {
reverse(s, 0, len(s)-1)
}
func reverse(s []byte, left int, right int) {
if left >= right {
return
}
s[left], s[right] = s[right], s[left]
reverse(s, left+1, right-1)
}```
### 3、复杂度分析
- **时间复杂度**:O(n),每次递归都会调用一次 `交换` 操作,这需要 O(n) 的时间。
- **空间复杂度**:O(n),递归栈的深度可以达到 n。
## 三、总结
| 方案 | 时间复杂度 | 空间复杂度 | 备注 |
| ---- | ----- | ----- | ------ |
| 双指针法 | O(n) | O(1) | 简单高效 |
| 递归法 | O(n) | O(n) | 递归交换字符 |
双指针法是解决这个问题的最佳方案,因为它不仅简单易懂,而且满足了空间复杂度的要求。