From cb6b28c11b394f7d2b0af25240f52a5c0ca147ec Mon Sep 17 00:00:00 2001 From: CyC2018 Date: Fri, 30 Oct 2026 20:18:05 +0800 Subject: [PATCH] =?UTF-8?q?Update=205.=20=E6=9B=BF=E6=8D=A2=E7=A9=BA?= =?UTF-8?q?=E6=A0=BC.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新题目说明,补充双指针从后往前替换空格的推演示例与 Java 实现代码,并补充替换前后长度不变场景的说明。 --- notes/5. 替换空格.md | 51 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/notes/5. 替换空格.md b/notes/5. 替换空格.md index d20a4afb..e415bcd8 100644 --- a/notes/5. 替换空格.md +++ b/notes/5. 替换空格.md @@ -6,7 +6,7 @@ ## 题目描述 -将一个字符串中的空格替换成 "%20"。(在 LeetCode 上对应原题为 LCR 122. 路径加密,题意要求将 '.' 替换为空格) +将一个字符串中的每个空格替换成 "%20"。 ```text Input: @@ -16,10 +16,55 @@ Output: "A%20B" ``` +力扣上对应的 LCR 122“路径加密”改成了把 '.' 替换为空格,替换前后长度不变,代码见[替换前后长度不变的情况](#替换前后长度不变的情况)。 + ## 解题思路 -① 遍历字符串,统计需要替换字符的个数,据此计算出替换后所需的新长度。 -② 双指针或 StringBuilder 处理:遍历原字符串,遇到目标字符则追加替换后的内容,其余字符原样复制。 +Java 的 String 不可变,最直接的做法是用 StringBuilder 逐个字符复制,遇到空格追加 "%20",时间和空间复杂度都是 O(N)。 + +原题考查的是在原数组上替换,假设数组末尾有足够的空余位置。如果从前往后替换,每遇到一个空格,它后面的所有字符都要后移 2 位,最坏 O(N2)。从后往前填可以让每个字符只移动一次: + +- 先统计空格个数,新长度 = 原长度 + 2 × 空格数; +- P1 指向原字符串的末尾,P2 指向新长度的末尾,P1 从后往前扫描:普通字符复制到 P2,空格则在 P2 处从后往前依次写入 '0'、'2'、'%'; +- P1 与 P2 相遇时,前面已经没有空格,结束。 + +以 "A B C" 为例(_ 表示空格),原长度 5,新长度 9: + +```text +下标 0 1 2 3 4 5 6 7 8 +初始 A _ B _ C P1 = 4,P2 = 8 +复制 C A _ B _ C C P1 = 3,P2 = 7 +空格写 %20 A _ B _ C % 2 0 C P1 = 2,P2 = 4 +复制 B A _ B _ B % 2 0 C P1 = 1,P2 = 3 +空格写 %20 A % 2 0 B % 2 0 C P1 = 0,P2 = 0,相遇 +``` + +```java +public String replaceSpace(String s) { + int spaces = 0; + for (int i = 0; i < s.length(); i++) + if (s.charAt(i) == ' ') + spaces++; + // 模拟末尾留有足够空间的字符数组 + char[] chars = Arrays.copyOf(s.toCharArray(), s.length() + 2 * spaces); + int p1 = s.length() - 1, p2 = chars.length - 1; + while (p1 >= 0 && p1 < p2) { + char c = chars[p1--]; + if (c == ' ') { + chars[p2--] = '0'; + chars[p2--] = '2'; + chars[p2--] = '%'; + } else { + chars[p2--] = c; + } + } + return new String(chars); +} +``` + +### 替换前后长度不变的情况 + +LCR 122 把 '.' 换成空格,一个字符换一个字符,不涉及移动,逐个复制即可。 ```java public String pathEncryption(String path) {