151. 反转字符串中的单词
func reverseWords(s string) string {
ss := []byte(s)
Len := len(ss)
//1.去除多余空格
slow := 0
for fast := 0; fast < Len; fast++ {
if ss[fast] != ' ' { //遇到不是空格就处理
if slow != 0 { //如果slow不是指向第0个位置,那么每次fast指向新的字母时就要先空出一个空格
ss[slow] = ' '
slow++
}
for fast < Len && ss[fast] != ' ' {
ss[slow] = ss[fast]
slow++
fast++
}
}
}
ss = ss[:slow] //注意这里slow不用再+1
fmt.Println(string(ss))
//2.全部反转
reverse(ss, 0, len(ss)-1)
fmt.Println(string(ss))
//3.对应单词再反转过来i单词开始位置,j单词结束位置
i := 0
for i < len(ss) {
j := i
for j < len(ss) && ss[j] != ' ' {
j++
}
reverse(ss, i, j-1)
i = j
i++
}
return string(ss)
}
func reverse(b []byte, left, right int) {
for left < right {
b[left], b[right] = b[right], b[left]
left++
right--
}
}
这道题目可以说是综合考察了字符串的多种操作
现在只考虑用最优解解答此题,当中有些环节或许可以用一些易于想到的简单思路(暴力遍历)解决,此处暂时不做考虑
- 步骤1.去除多余空格
包括:
字符串最前方空格
单词之间多余空格
字符串后方空格
采用双指针,思路参考27.移除元素
小细节:每次fast指向新的字母时slow就要先空出一个空格,slow指向第0个位置时除外
- 步骤2.全部反转
ss = ss[:slow] //注意这里slow不用再+1
将缩短后的ss全部反转
这里把反转抽象成一个函数。注意:这里不用&ss
传地址,因为本来[]byte
就是引用传递,底层数组会直接跟着变化。
- 步骤3.对应单词再反转过来
代码很妙,细细体会学习