题目描述
给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:
javascript
输入: "the sky is blue"
输出: "blue is sky the"
示例 2:
javascript
输入: " hello world! "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
javascript
输入: "a good example"
输出: "example good a"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
说明:
- 无空格字符构成一个单词。
- 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
解题思路
类比和解题步骤
考虑类比:假设你有一篇文章,你希望将其中的每个单词逐个翻转。你可以通过先将整个文章逐字符翻转,然后再对每个单词逐字符翻转,最终得到逐个翻转单词的结果。
- 整体翻转字符串: 对整个字符串进行逐字符翻转。
- 逐个翻转单词: 对每个单词进行逐字符翻转,得到最终结果。
特殊案例
- 如果输入字符串为空,则直接返回空字符串。
C#代码实现
java
public string ReverseWords(string s) {
if (string.IsNullOrEmpty(s)) {
return s;
}
char[] charArray = s.ToCharArray();
int n = charArray.Length;
// 整体翻转字符串
Reverse(charArray, 0, n - 1);
// 逐个翻转单词
ReverseWords(charArray, n);
// 去除多余空格并转为字符串
return CleanSpaces(charArray, n);
}
private void Reverse(char[] charArray, int start, int end) {
while (start < end) {
char temp = charArray[start];
charArray[start] = charArray[end];
charArray[end] = temp;
start++;
end--;
}
}
private void ReverseWords(char[] charArray, int n) {
int start = 0;
int end = 0;
while (start < n) {
while (end < n && charArray[end] != ' ') {
end++;
}
Reverse(charArray, start, end - 1);
start = end + 1;
end++;
}
}
private string CleanSpaces(char[] charArray, int n) {
int i = 0;
int j = 0;
while (j < n) {
// 跳过多余空格
while (j < n && charArray[j] == ' ') {
j++;
}
// 复制非空格字符
while (j < n && charArray[j] != ' ') {
charArray[i] = charArray[j];
i++;
j++;
}
// 跳过多余空格
while (j < n && charArray[j] == ' ') {
j++;
}
// 添加一个空格分隔单词
if (j < n) {
charArray[i] = ' ';
i++;
}
}
return new string(charArray, 0, i);
}
C代码实现
c
void reverse(char* s, int start, int end) {
while (start < end) {
char temp = s[start];
s[start] = s[end];
s[end] = temp;
start++;
end--;
}
}
void reverseWords(char* s) {
int n = strlen(s);
// 整体翻转字符串
reverse(s, 0, n - 1);
int start = 0;
int end = 0;
while (start < n) {
// 跳过多余空格
while (end < n && s[end] == ' ') {
end++;
}
// 逐个翻转单词
reverse(s, start, end - 1);
start = end + 1;
end++;
}
int i = 0;
int j = 0;
while (j < n) {
// 跳过多余空格
while (j < n && s[j] == ' ') {
j++;
}
// 复制非空格字符
while (j < n && s[j] != ' ') {
s[i] = s[j];
i++;
j++;
}
// 跳过多余空格
while (j < n && s[j] == ' ') {
j++;
}
// 添加一个空格分隔单词
if (j < n) {
s[i] = ' ';
i++;
}
}
// 添加字符串结尾
s[i] = '\0';
}
时间复杂度和空间复杂度
- 时间复杂度:O(n),其中 n 是字符串的长度。整体翻转字符串和逐个翻转单词的时间复杂度均为 O(n)。
- 空间复杂度:O(1)。只使用了常数级别的额外空间。