@@ -98,10 +98,122 @@ class Solution {
9898
99998ms 击败 36.06%
100100
101- # v2-优化?
101+ # v2-反转
102+
103+ ## 思路
104+
105+ 1)整体反转
106+
107+ 2)反转每一个单词
108+
109+ 3)去除空格
110+
111+ ## 实现
112+
113+ ``` java
114+ public class Solution {
115+ public String reverseWords (String s ) {
116+ if (s == null || s. length() == 0 ) return s;
117+ char [] ch = s. toCharArray();
118+ int n = ch. length;
119+
120+ // 1. 整体翻转
121+ reverse(ch, 0 , n - 1 );
122+
123+ // 2. 单词内部翻转
124+ int i = 0 ;
125+ while (i < n) {
126+ while (i < n && ch[i] == ' ' ) i++ ; // 跳过空格
127+ if (i == n) break ;
128+ int j = i;
129+ while (j < n && ch[j] != ' ' ) j++ ; // 找单词尾
130+ reverse(ch, i, j - 1 ); // 翻转单词
131+ i = j;
132+ }
133+
134+ // 3. 快慢指针去重空格
135+ int slow = 0 ;
136+ for (int fast = 0 ; fast < n; fast++ ) {
137+ if (ch[fast] != ' ' ) { // 遇到非空格
138+ if (slow != 0 ) ch[slow++ ] = ' ' ; // 单词间补一个空格
139+ while (fast < n && ch[fast] != ' ' )
140+ ch[slow++ ] = ch[fast++ ];
141+ }
142+ }
143+ // 4. 截取有效部分
144+ return new String (ch, 0 , slow);
145+ }
146+
147+ // 双指针翻转 [l, r]
148+ private void reverse (char [] ch , int l , int r ) {
149+ while (l < r) {
150+ char tmp = ch[l];
151+ ch[l++ ] = ch[r];
152+ ch[r-- ] = tmp;
153+ }
154+ }
155+
156+ }
157+ ```
158+
159+ ## 效果
160+
161+ 2ms 击败 98.18%
162+
163+
164+ # v3-逆向
165+
166+ ## 思路
167+
168+ 如何避免反转呢?
169+
170+ 从尾巴往前扫,遇到空格就跳过;遇到非空格就定位到当前单词头,把头到尾这一坨原样追加到 sb 里,再在单词后面补一个空格;最后把末尾多补的那个空格删掉即可。
171+
172+ 时间复杂度 O(n),额外空间 O(n)(仅结果占用)。
173+
174+
175+ ## 实现
176+
177+ ``` java
178+ public class Solution {
179+ public String reverseWords (String s ) {
180+ if (s == null || s. length() == 0 ) return s;
181+ char [] ch = s. toCharArray();
182+ int n = ch. length;
183+ StringBuilder sb = new StringBuilder ();
184+
185+ int r = n - 1 ;
186+ while (r >= 0 ) {
187+ // 1. 跳过尾部空格
188+ while (r >= 0 && ch[r] == ' ' ) r-- ;
189+ if (r < 0 ) break ;
190+
191+ // 2. 找单词左边界
192+ int l = r;
193+ while (l >= 0 && ch[l] != ' ' ) l-- ;
194+
195+ // 3. 把单词 [l+1, r] 原样追加
196+ sb. append(ch, l + 1 , r - l). append(' ' );
197+
198+ // 4. 继续往前
199+ r = l;
200+ }
201+
202+ // 5. 删掉最后多补的空格
203+ if (sb. length() > 0 ) sb. setLength(sb. length() - 1 );
204+ return sb. toString();
205+ }
206+ }
207+ ```
208+
209+ ## 效果
210+
211+ 3ms 击败 93.00%
102212
103213
214+ ## 反思
104215
216+ 最满足题意的还是方式2
105217
106218# 开源地址
107219
0 commit comments