【LeetCode】151. 反转字符串中的单词
解题思路
该问题要求反转字符串中的单词顺序并规范空格处理,核心挑战在于高效处理多余空格和保持单词顺序反转。采用以下策略:
- 预处理空格:去除首尾空格并合并连续空格(
strings.TrimSpace和strings.Fields函数)。 - 分割单词:将字符串按单词分割为数组。
- 反转数组:通过双指针或数组反转实现单词顺序反转。
- 重组字符串:用单个空格连接反转后的单词。
关键步骤
-
空格处理
使用strings.Fields()函数自动处理所有空格(包括前导、尾随和连续空格),返回无空元素的单词数组。 -
单词反转
将分割后的单词数组首尾交换。 -
字符串重组
用strings.Join()连接单词数组,确保单词间仅有一个空格。
func reverseWords(s string) string { // 预处理空格并分割单词(自动处理所有多余空格) words := strings.Fields(s) // 反转单词数组(双指针法) for i, j := 0, len(words)-1; i < j; i, j = i+1, j-1 { words[i], words[j] = words[j], words[i] } // 重组字符串(单词间单个空格) return strings.Join(words, " ") }
复杂度分析
| 指标 | 值 | 说明 |
|---|---|---|
| 时间复杂度 | O(n) | 分割、反转、连接均线性复杂度 |
| 空间复杂度 | O(n) | 存储单词数组 |
测试用例验证
func main() { // 示例1 s1 := "the sky is blue" fmt.Println(reverseWords(s1)) // 输出: "blue is sky the" // 示例2 s2 := " hello world " fmt.Println(reverseWords(s2)) // 输出: "world hello" // 示例3 s3 := "a good example" fmt.Println(reverseWords(s3)) // 输出: "example good a" }
核心逻辑解析
-
预处理与分割
strings.Fields()是 Golang 中专门处理空格分割的函数,其底层实现通过状态机自动跳过连续空格,比手动循环更高效。 -
反转优化
使用首尾双指针交换元素(时间复杂度 O(n/2)),相比递归或辅助栈更节省内存。 -
边界处理
输入空字符串或纯空格时,strings.Fields()返回空数组,strings.Join()自动处理为空字符串,无需额外判断。
实现对比
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 双指针遍历 | 无需分割字符串(内存优化) | 代码复杂度高 | 内存敏感场景 |
| 分割+反转 | 代码简洁易维护 | 需要存储单词数组 | 常规开发场景 |

浙公网安备 33010602011771号