This commit is contained in:
youngyangyang04
2021-06-21 10:12:10 +08:00
parent 5f5527800c
commit aa87376071
7 changed files with 60 additions and 99 deletions

View File

@@ -16,19 +16,19 @@ https://leetcode-cn.com/problems/reverse-words-in-a-string/
给定一个字符串,逐个翻转字符串中的每个单词。
示例 1
输入: "the sky is blue"
输出: "blue is sky the"
示例 1
输入: "the sky is blue"
输出: "blue is sky the"
示例 2
输入: "  hello world!  "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 2
输入: "  hello world!  "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3
输入: "a good   example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
示例 3
输入: "a good   example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
# 思路
@@ -50,12 +50,15 @@ https://leetcode-cn.com/problems/reverse-words-in-a-string/
* 将整个字符串反转
* 将每个单词反转
如动画所示:
举个例子,源字符串为:"the sky is blue "
![151翻转字符串里的单词](https://tva1.sinaimg.cn/large/008eGmZEly1gp0kv5gl4mg30gy0c4nbp.gif)
* 移除多余空格 : "the sky is blue"
* 字符串反转:"eulb si yks eht"
* 单词反转:"blue is sky the"
这样我们就完成了翻转字符串里的单词。
思路很明确了,我们说一说代码的实现细节,就拿移除多余空格来说,一些同学会上来写如下代码:
```C++
@@ -80,13 +83,13 @@ void removeExtraSpaces(string& s) {
如果不仔细琢磨一下erase的时间复杂读还以为以上的代码是O(n)的时间复杂度呢。
想一下真正的时间复杂度是多少一个erase本来就是O(n)的操作erase实现原理题目[数组:就移除个元素很难么?](https://mp.weixin.qq.com/s/wj0T-Xs88_FHJFwayElQlA)最优的算法来移除元素也要O(n)。
想一下真正的时间复杂度是多少一个erase本来就是O(n)的操作erase实现原理题目[数组:就移除个元素很难么?](https://mp.weixin.qq.com/s/RMkulE4NIb6XsSX83ra-Ww)最优的算法来移除元素也要O(n)。
erase操作上面还套了一个for循环那么以上代码移除冗余空格的代码时间复杂度为O(n^2)。
那么使用双指针法来去移除空格最后resize重新设置一下字符串的大小就可以做到O(n)的时间复杂度。
如果对这个操作比较生疏了,可以再看一下这篇文章:[数组:就移除个元素很难么?](https://mp.weixin.qq.com/s/wj0T-Xs88_FHJFwayElQlA)是如何移除元素的。
如果对这个操作比较生疏了,可以再看一下这篇文章:[数组:就移除个元素很难么?](https://mp.weixin.qq.com/s/RMkulE4NIb6XsSX83ra-Ww)是如何移除元素的。
那么使用双指针来移除冗余空格代码如下: fastIndex走的快slowIndex走的慢最后slowIndex就标记着移除多余空格后新字符串的长度。
@@ -122,7 +125,7 @@ void removeExtraSpaces(string& s) {
此时我们已经实现了removeExtraSpaces函数来移除冗余空格。
还做实现反转字符串的功能,支持反转字符串子区间,这个实现我们分别在[字符串:这道题目,使用库函数一行代码搞定](https://mp.weixin.qq.com/s/X02S61WCYiCEhaik6VUpFA)和[字符串:简单的反转还不够!](https://mp.weixin.qq.com/s/XGSk1GyPWhfqj2g7Cb1Vgw)里已经讲过了。
还做实现反转字符串的功能,支持反转字符串子区间,这个实现我们分别在[344.反转字符串](https://mp.weixin.qq.com/s/_rNm66OJVl92gBDIbGpA3w)和[541.反转字符串II](https://mp.weixin.qq.com/s/pzXt6PQ029y7bJ9YZB2mVQ)里已经讲过了。
代码如下:
@@ -135,11 +138,8 @@ void reverse(string& s, int start, int end) {
}
```
## 本题C++整体代码
本题C++整体代码
效率:
<img src='https://code-thinking.cdn.bcebos.com/pics/151_%E7%BF%BB%E8%BD%AC%E5%AD%97%E7%AC%A6%E4%B8%B2%E9%87%8C%E7%9A%84%E5%8D%95%E8%AF%8D.png' width=600> </img></div>
```C++
// 版本一
@@ -203,6 +203,7 @@ public:
return s;
}
// 当然这里的主函数reverseWords写的有一些冗余的可以精简一些精简之后的主函数为
/* 主函数简单写法
string reverseWords(string s) {
removeExtraSpaces(s);
@@ -220,25 +221,8 @@ public:
};
```
当然这里的主函数reverseWords写的有一些冗余的可以精简一些精简之后的主函数为
```C++
// 注意这里仅仅是主函数,其他函数和版本一一致
string reverseWords(string s) {
removeExtraSpaces(s);
reverse(s, 0, s.size() - 1);
for(int i = 0; i < s.size(); i++) {
int j = i;
// 查找单词间的空格,翻转单词
while(j < s.size() && s[j] != ' ') j++;
reverse(s, i, j - 1);
i = j;
}
return s;
}
```
效率
<img src='https://code-thinking.cdn.bcebos.com/pics/151_翻转字符串里的单词.png' width=600> </img></div>
@@ -316,7 +300,6 @@ class Solution {
}
```
Python
Go