题目
**给你一个字符串 s ,逐个翻转字符串中的所有 单词 。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
请你返回一个翻转 s 中单词顺序并用单个空格相连的字符串。
说明:
**输入字符串 s 可以在前面、后面或者单词间包含多余的空格。
翻转后单词间应当仅用一个空格分隔。
翻转后的字符串中不应包含额外的空格。**
解题思路
方法一:自行编写对应的函数
我们也可以不使用语言中的 API,而是自己编写对应的函数。在不同语言中,这些函数实现是不一样的,主要的差别是有些语言的字符串不可变(如 Java 和 Python),有些语言的字符串可变(如 C++)。
对于字符串不可变的语言,首先得把字符串转化成其他可变的数据结构,同时还需要在转化的过程中去除空格。
对于字符串可变的语言,就不需要再额外开辟空间了,直接在字符串上原地实现。在这种情况下,反转字符和去除空格可以一起完成。
C++实现
class Solution {
public:
string reverseWords(string s) {
// 反转整个字符串
reverse(s.begin(), s.end());
int n = s.size();
int idx = 0;//
for (int start = 0; start < n; ++start) {
if (s[start] != ' ') {
// 填一个空白字符然后将idx移动到下一个单词的开头位置
if (idx != 0)
s[idx++] = ' ';
// 循环遍历至单词的末尾
int end = start;
while (end < n && s[end] != ' ')
s[idx++] = s[end++];
// 反转整个单词
reverse(s.begin()+idx-end+start, s.begin() + idx);
// 更新start,去找下一个单词
start = end;
}
}
s.erase(s.begin() + idx, s.end()); //去除(s.begin() + idx, s.end())之间的空格,是开区间
return s;
}
};
- 时间复杂度:O(n),其中 n 为输入字符串的长度。
- 空间复杂度:O(1)
题目二:左旋转字符串
字符串汇总的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。例如,输入字符串“abcdefg”和数字2,该函数将返回左旋转两位得到的结果“cdefgab”。
解题思路
在翻转字符串的基础上,只需对要操作的字符串进行三次翻转即可。
C++实现
class Solution
{
public:
void Reverse(char *pBegin, char*pEnd)
{
while (pBegin < pEnd)
{
char temp = *pBegin;
*pBegin = *pEnd;
*pEnd = temp;
pBegin++;
pEnd--;
}
}
void *LeftRotateString(char*pStr, int n)
{
int nLength = static_cast<int>(strlen(pStr));
if (!pStr)
return 0;
char *pBegin = pStr, *pEnd = pStr;
while (*pEnd != '\0')
pEnd++;
pEnd--;
//第一次整个翻转字符串
Reverse(pBegin, pEnd);
pBegin = pEnd = pStr;
//第二次整个翻转字符串
Reverse(pBegin, pBegin + nLength-n - 1);
//第三次整个翻转字符串
Reverse(pBegin + nLength - n, pBegin + nLength - 1);
}
};
- 时间复杂度:O(n),主要为翻转的时间
- 空间复杂度:O(1)