|
| 1 | +/* |
| 2 | + * @Author: Chacha |
| 3 | + * @Date: 2022-03-17 15:01:30 |
| 4 | + * @Last Modified by: Chacha |
| 5 | + * @Last Modified time: 2022-03-17 18:01:59 |
| 6 | + */ |
| 7 | + |
| 8 | +/** |
| 9 | + * 来源:https://leetcode-cn.com/problems/reverse-words-in-a-string/ |
| 10 | + * |
| 11 | + * 151. 颠倒字符串中的单词 |
| 12 | + * |
| 13 | + * 给你一个字符串 s ,颠倒字符串中单词的顺序。单词是由非空格字符组成的字符串。 |
| 14 | + * s 中使用至少一个空格将字符串中的单词分隔开。返回单词顺序颠倒且单词之间用单个空格连接的结果字符串。 |
| 15 | + * 注意:输入字符串 s 中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中, |
| 16 | + * 单词间应当仅用单个空格分隔,且不包含任何额外的空格。 |
| 17 | + * |
| 18 | + * 提示: |
| 19 | + * 1 <= s.length <= 10^4 |
| 20 | + * s 包含英文大小写字母、数字和空格 ' ' |
| 21 | + * s 中至少存在一个单词 |
| 22 | + * |
| 23 | + * 进阶:如果字符串在你使用的编程语言中是一种可变数据类型,请尝试使用 O(1) 额外空间复杂度的 原地 解法。 |
| 24 | + * |
| 25 | + * 示例 1: |
| 26 | + * 输入:s = "the sky is blue" |
| 27 | + * 输出:"blue is sky the" |
| 28 | + * |
| 29 | + * 示例 2: |
| 30 | + * 输入:s = " hello world " |
| 31 | + * 输出:"world hello" |
| 32 | + * 解释:颠倒后的字符串中不能存在前导空格和尾随空格。 |
| 33 | + * |
| 34 | + * 示例 3: |
| 35 | + * 输入:s = "a good example" |
| 36 | + * 输出:"example good a" |
| 37 | + * 解释:如果两个单词间有多余的空格,颠倒后的字符串需要将单词间的空格减少到仅有一个。 |
| 38 | + * |
| 39 | + */ |
| 40 | + |
| 41 | +#include <iostream> |
| 42 | +#include <vector> |
| 43 | +#include <string> |
| 44 | + |
| 45 | +using namespace std; |
| 46 | + |
| 47 | +class Solution |
| 48 | +{ |
| 49 | +public: |
| 50 | + string reverseWords(string s); |
| 51 | + |
| 52 | + void removeExtraSpaces(string &s); |
| 53 | + |
| 54 | + void reverse(string &s, int start, int end); |
| 55 | +}; |
| 56 | + |
| 57 | +/** |
| 58 | + * 双指针法 |
| 59 | + * |
| 60 | + * 解题思路如下: |
| 61 | + * 1. 移除多余空格 |
| 62 | + * 2. 将整个字符串反转 |
| 63 | + * 3. 将每个单词反转 |
| 64 | + * |
| 65 | + * 空间复杂度: O(1) |
| 66 | + * |
| 67 | + */ |
| 68 | +string Solution::reverseWords(string s) |
| 69 | +{ |
| 70 | + removeExtraSpaces(s); |
| 71 | + |
| 72 | + cout << "移除空格之后" << s << endl; |
| 73 | + |
| 74 | + reverse(s, 0, s.size() - 1); |
| 75 | + |
| 76 | + cout << "处理字符串之后" << s << endl; |
| 77 | + |
| 78 | + for (int i = 0; i < s.size(); i++) |
| 79 | + { |
| 80 | + int j = i; |
| 81 | + |
| 82 | + while (j < s.size() && s[j] != ' ') |
| 83 | + j++; |
| 84 | + |
| 85 | + reverse(s, i, j - 1); |
| 86 | + i = j; |
| 87 | + } |
| 88 | + |
| 89 | + cout << "颠倒字符串之后" << s << endl; |
| 90 | + |
| 91 | + return s; |
| 92 | +}; |
| 93 | + |
| 94 | +/** |
| 95 | + * 快慢指针法移除多余空格 |
| 96 | + */ |
| 97 | +void Solution::removeExtraSpaces(string &s) |
| 98 | +{ |
| 99 | + int i = 0, j = 0; |
| 100 | + |
| 101 | + // 去掉字符串前面的空格 |
| 102 | + while (s.size() > 0 && j < s.size() && s[j] == ' ') |
| 103 | + { |
| 104 | + j++; |
| 105 | + } |
| 106 | + |
| 107 | + for (; j < s.size(); j++) |
| 108 | + { |
| 109 | + // 去掉字符串中间部分的冗余空格 |
| 110 | + if (j - 1 > 0 && s[j - 1] == s[j] && s[j] == ' ') |
| 111 | + { |
| 112 | + continue; |
| 113 | + } |
| 114 | + else |
| 115 | + { |
| 116 | + s[i++] = s[j]; |
| 117 | + } |
| 118 | + } |
| 119 | + |
| 120 | + if (i - 1 > 0 && s[i - 1] == ' ') |
| 121 | + { // 去掉字符串末尾的空格 |
| 122 | + s.resize(i - 1); |
| 123 | + } |
| 124 | + else |
| 125 | + { |
| 126 | + s.resize(i); // 重新设置字符串大小 |
| 127 | + } |
| 128 | +} |
| 129 | + |
| 130 | +/** |
| 131 | + * 双指针法翻转字符串 |
| 132 | + * |
| 133 | + * 反转字符串s中左闭又闭的区间[start, end] |
| 134 | + * |
| 135 | + */ |
| 136 | +void Solution::reverse(string &s, int start, int end) |
| 137 | +{ |
| 138 | + for (int i = start, j = end; i < j; i++, j--) |
| 139 | + { |
| 140 | + swap(s[i], s[j]); |
| 141 | + } |
| 142 | +}; |
| 143 | + |
| 144 | +int main(int argc, char const *argv[]) |
| 145 | +{ |
| 146 | + Solution s; |
| 147 | + string str = "the sky is blue"; |
| 148 | + string str1 = " hello world "; |
| 149 | + |
| 150 | + s.reverseWords(str); |
| 151 | + s.reverseWords(str1); |
| 152 | + |
| 153 | + return 0; |
| 154 | +} |
0 commit comments