题目
给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:
输入: "the sky is blue"
输出: "blue is sky the"
示例 2:
输入: " hello world! "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: "a good example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
说明:
无空格字符构成一个单词。
输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-words-in-a-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法一:模拟栈解法
Go实现代码
func reverseWords(s string) string {
i := 0
//去除空格前缀.
for i < len(s) && s[i] == ' ' {
i++
}
//全为空格的情况直接返回空.
if i == len(s) {
return ""
}
//用string切片数组模拟栈.
var stack []string
wordBytes := make([]byte, 0)
for i < len(s) {
if s[i] != ' ' {
//非空格字符(即有效单词字符)加入到临时单词存储byte切片中.
wordBytes = append(wordBytes, s[i])
} else if (len(wordBytes) > 0) {
//当前字符为空格,且单词缓存区里存在字符,则表示前一个单词结束,将其加入结果单词栈中,并清空单词缓存区.
stack = append(stack, string(wordBytes))
wordBytes = make([]byte, 0)
}
i++
}
//如上面判断结束,缓存区仍有內容,则表示存在最后一个单词后无空格的情况,则将缓存区內容即最后一个单词,加入栈中.
if (len(wordBytes) > 0) {
stack = append(stack, string(wordBytes))
}
ans := ""
//从后往前遍历stack(string型切片),模拟出栈过程,实现翻转字符串单词功能.
for j := len(stack) - 1; j >= 0; j-- {
ans += stack[j]
//非最后一个单词后面都要加上一个空格,表示单词分割.
if j > 0 {
ans += " "
}
}
return ans
}
进一步优化的思路
- 利用好切片的特点,通过s[startIndx:endIndex]的方式实现取字符串片段,从而去掉wordBytes缓存区的概念,当然使用缓存区的思路可以使用于更多欸字符串获取要进一步处理字符的情况,可视具体情况选用。
- 原地修改法。具体可参考Go实例代码1(提交记录0ms范例找到的,好像看不到提交作者,提交作者如果看到的话,可以联系我,补上题解作者信息)
Go实例代码1
func reverseWords(s string) string {
bytes := []byte(s)
//反转
for i,j := 0,len(bytes)-1; i <= j; i,j=i+1, j-1 {
bytes[j], bytes[i] = bytes[i], bytes[j]
}
for t, k := 0, 0; k < len(bytes) && t < len(bytes); k++ {
if bytes[t]== 32 {
copy(bytes[t:], bytes[t+1:])
bytes = bytes[:len(bytes)-1]
if k > 0 {
k--
}
continue
}
if (bytes[k] == 32 && bytes[t] != 32) || k== len(bytes)-1 {
for bytes[len(bytes)-1] == 32 && k == len(bytes)-1 {
bytes = bytes[:len(bytes)-1]
k = k - 1
}
o := k-1
if k == len(bytes)-1 {
o = k
}
for x,y := t, o; x <= y; x,y = x+1, y-1 {
bytes[x], bytes[y] = bytes[y], bytes[x]
}
t = k+1
}
}
x := len(bytes)-1
for x >= 0 {
if bytes[x] == 32 {
x--
} else {
break
}
}
bytes = bytes[:x+1]
return string(bytes)
}
此外,看到个别题解中有使用Go list双向链表数据结构实现栈,这里mark下看到的一篇关于Go list用法的文章:
https://blog.csdn.net/chenbaoke/article/details/42780895?utm_campaign=studygolang.com&utm_medium=studygolang.com&utm_source=studygolang.com