LeetCode 补充题 11. 翻转 URL 字符串里的单词
题目描述
给定字符串
s,其中单词之间使用完整子串%20分隔。请反转单词的排列顺序,并返回处理后的字符串。每个单词内部的字符顺序保持不变。输出首尾不保留分隔符,相邻单词之间恰好使用一个
%20;连续分隔符形成的空片段不作为单词。
示例 1:
输入:s = "hello%20world%20java"
输出:"java%20world%20hello"
示例 2:
输入:s = "%20hello%20%20world%20"
输出:"world%20hello"
提示:
-
%20是完整的三字符分隔符,不对其他 URL 编码进行解码。 -
%20以外的字符仍属于单词内容。 - 没有有效单词时返回空字符串。
题意分析
本篇按
%20分隔单词的约定处理:反转单词的先后顺序,保留每个单词内部的内容;输出首尾不含分隔符,相邻单词之间仅保留一个%20。这里的分隔符是连续三个字符组成的完整子串。处理目标是单词顺序,其他字符仍属于单词内容,无需解析或解码整个 URL。
解法:按 %20 切分后逆序拼接
核心思路
[!blue]
先按完整的
%20切分字符串。每个非空片段对应一个单词,片段内部的字符没有被改动,得到的片段顺序也与原串词序相同。首尾分隔符和连续分隔符可能产生空片段,它们不代表实际单词,应在切分后过滤掉。这样剩余列表只保存单词,后续无需再区分多余分隔符原来位于哪里。
接下来把单词列表倒序输出,再用一个
%20连接相邻单词。每个单词恰好出现一次,原来靠后的单词先输出,因此词序被反转;只调整片段顺序,不反转片段内容,词内字符保持原样。Java 从单词列表末尾向前追加,只有结果非空时才先补分隔符。Go 先交换首尾单词、逐步向中间移动,再用
strings.Join连接。两种写法都只在两个真实单词之间放分隔符;没有单词时自然得到空串。
解题步骤
- 用完整子串
%20切分输入,获得按原顺序排列的片段。- 逐个检查片段,只把非空片段加入单词列表。
- Java 倒序遍历单词列表,按需补
%20后追加单词;Go 用双指针反转列表,再以%20连接。- 返回结果。只有一个单词时保持原样,没有单词时返回空串。
代码实现
class Solution {
public String reverseWords(String s) {
String[] parts = s.split("%20");
List<String> words = new ArrayList<>();
for (String part : parts) {
// 过滤完整分隔符产生的空片段,统一处理首尾和连续分隔
if (!part.isEmpty()) {
words.add(part);
}
}
StringBuilder answer = new StringBuilder();
for (int i = words.size() - 1; i >= 0; i--) {
// 仅在两个真实单词之间追加一个分隔符
if (answer.length() > 0) {
answer.append("%20");
}
answer.append(words.get(i));
}
return answer.toString();
}
}
import "strings"
func reverseWords(s string) string {
parts := strings.Split(s, "%20")
words := make([]string, 0, len(parts))
for _, part := range parts {
// 过滤完整分隔符产生的空片段,统一处理首尾和连续分隔
if part != "" {
words = append(words, part)
}
}
// 先反转单词列表,再由连接函数插入统一分隔符
for left, right := 0, len(words)-1; left < right; left, right = left+1, right-1 {
words[left], words[right] = words[right], words[left]
}
return strings.Join(words, "%20")
}
复杂度分析
设输入长度为
n,实际单词数为w。
- 时间复杂度:$O(n)$。分隔符长度固定,切分及过滤所有片段共需线性时间;反转单词顺序为 $O(w)$,拼接的总字符数不超过原串长度。
- 空间复杂度:$O(n)$。切分结果、单词列表及输出缓冲区总共使用线性空间。
关键点总结
[!green]
- 识别的是完整
%20,不能把它拆成单字符分隔规则。- 空片段只表示多余分隔符,过滤后才得到真正的单词序列。
- 反转单词列表的顺序,并按固定分隔符重组,就能同时保留词内内容和规范词间间隔。
易错点总结
[!yellow]
- 按
%、2或0单个字符切分,会破坏本来属于单词的内容。- 保留空片段参与连接,会把首尾或连续分隔符重新带回结果。
- 直接反转所有字符,会同时反转单词内部和
%20标记。- 先做通用 URL 解码,会改变其他编码字符,不符合本篇保留单词内容的约定。
- 每个单词后都追加
%20会留下尾部分隔符;应只在相邻单词之间插入。
相似题目
| 题目 | 难度 | 关联与区别 |
|---|---|---|
| 151. 反转字符串中的单词 | 中等 | 单词顺序翻转相同,本题分隔符是完整的%20标记,而不是单个空格字符。 |
转载与许可
许可
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!