mirror of
https://github.com/CyC2018/Interview-Notebook.git
synced 2026-10-31 11:05:36 +00:00
Update 5. 替换空格.md
更新题目说明,补充双指针从后往前替换空格的推演示例与 Java 实现代码,并补充替换前后长度不变场景的说明。
This commit is contained in:
+48
-3
@@ -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(N<sup>2</sup>)。从后往前填可以让每个字符只移动一次:
|
||||
|
||||
- 先统计空格个数,新长度 = 原长度 + 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) {
|
||||
|
||||
Reference in New Issue
Block a user