网站救助计划
1.为阅读体验,本站无任何广告,也无任何盈利方法,站长一直在用爱发电,现濒临倒闭,希望有能力的同学能帮忙分担服务器成本
2.捐助10元及以上同学,可添加站长微信lurenzhang888,备注捐助,网站倒闭后可联系站长领取本站pdf内容
3.若网站能存活下来,后续将会持续更新内容
题目描述
输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串”I am a student. “,则输出”student. a am I”。
示例 1:
输入: "the sky is blue"
输出: "blue is sky the"
示例 2:
输入: " hello world! "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: "a good example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
说明:
- 无空格字符构成一个单词。
- 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
- 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
题解
(字符串翻转) O(n)
- 使用双指针算法先翻转每个单词
- 然后翻转整个字符串
但在字符串的开头、中间、结尾都可能会有空格,我们需要把这三部分多余的空格去掉,只保留每个单词之间的空格。而且题目要求使用 O(1) 的空间完成,所以只能复用字符串,用一个指针 k 从前往后存储有效的字符部分,翻转结束后 k 后面多余的字符都删掉。
[i, j] 单词部分放到 [k, t] 位置上。
时间复杂度
整个字符串需要被扫描两遍,所以时间复杂度为 O(n)
空间复杂度
O(1)
C++ 代码
class Solution {
public:
string reverseWords(string s) {
int k = 0;
for (int i = 0; i < s.size(); i ++ ) {
if (s[i] == ' ') continue;
// k 指向单词的开头,t 指向这个单词末尾的下一个位置
int j = i, t = k;
while (j < s.size() && s[j] != ' ') s[t ++ ] = s[j ++ ];
// 翻转单词 s[k]~s[t - 1]
reverse(s.begin() + k, s.begin() + t);
s[t ++ ] = ' ';
i = j, k = t;
}
// 翻转结束后 k 指向的是下一个单词的开头,现在让它指向前一个位置的空格
if (k) k -- ;
// 删除空格以及下标 k 后面的字符
s.erase(s.begin() + k, s.end());
reverse(s.begin(), s.end());
return s;
}
};
Java 代码
class Solution {
public String reverseWords(String s) {
String[] words = s.split(" ");
StringBuilder sb = new StringBuilder();
for (int i = words.length - 1; i >= 0; i -- ) {
if (!words[i].isEmpty()) {
sb.append(words[i]).append(" ");
}
}
return sb.toString().trim();
}
}
Python 代码
class Solution:
def reverseWords(self, s: str) -> str:
words = s.split()
words.reverse()
return ' '.join(words)
本文由读者提供,Github地址:https://github.com/tonngw
点击面试手册,获取本站面试手册PDF完整版