题目描述
给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:
输入: "the sky is blue"
输出: "blue is sky the"
示例 2:
输入: " hello world! "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: "a good example"
输出: "example good a"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
说明:
- 无空格字符构成一个单词。
- 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
解题思路
类比和解题步骤
考虑类比:假设你有一篇文章,你希望将其中的每个单词逐个翻转。你可以通过先将整个文章逐字符翻转,然后再对每个单词逐字符翻转,最终得到逐个翻转单词的结果。
- 整体翻转字符串: 对整个字符串进行逐字符翻转。
- 逐个翻转单词: 对每个单词进行逐字符翻转,得到最终结果。
特殊案例
- 如果输入字符串为空,则直接返回空字符串。
C#代码实现
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代码实现
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)。只使用了常数级别的额外空间。