Skip to content

Commit 948225e

Browse files
committed
[Feature] add for new
1 parent a1e8215 commit 948225e

File tree

1 file changed

+113
-1
lines changed

1 file changed

+113
-1
lines changed

src/posts/leetcode/topinterview-150/2025-11-17-array-28-LC151-reverse-words-in-a-string.md

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,122 @@ class Solution {
9898

9999
8ms 击败 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

Comments
 (0)