持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
剑指 Offer 05. 替换空格
leetcode:leetcode-cn.com/problems/ti…
GitHub:github.com/nateshao/le…
请实现一个函数,把字符串
s中的每个空格替换成"%20"。输入:s = "We are happy." 输出:"We%20are%20happy."限制: 0 <= s 的长度 <= 10000
方法一:遍历添加
遇到空格就在后面添加“ %20 ”
字符串都被设计成「不可变」的类型,即无法直接修改字符串的某一位字符,需要新建一个字符串实现。
算法流程:
-
初始化一个 list (Python) / StringBuilder (Java) ,记为 res ;
-
遍历列表 s 中的每个字符 c :
- 当 c 为空格时:向 res 后添加字符串 "%20" ;
- 当 c 不为空格时:向 res 后添加字符 c ;
- 将列表 res 转化为字符串并返回。
复杂度分析:
- 时间复杂度 O(N) : 遍历使用O(N) ,每轮添加(修改)字符操作使用 O(1) ;
- 空间复杂度 O(N): 新建的 StringBuilder 都使用了线性大小的额外空间。
package com.nateshao.sword_offer.topic_04_replaceSpace;
/**
* @date Created by 邵桐杰 on 2021/11/15 23:12
* @个人网站 www.nateshao.cn
* @博客 https://nateshao.gitee.io
* @GitHub https://github.com/nateshao
* @Gitee https://gitee.com/nateshao
* Description: 替换空格
*/
public class Solution {
public static void main(String[] args) {
String str = "We Are Happy";
String s = replaceSpace(str);
System.out.println(s);
}
public static String replaceSpace(String s) {
StringBuilder res = new StringBuilder();
for (Character c : s.toCharArray()) {
if (c == ' ') res.append("%20");
else res.append(c);
}
return res.toString();
// if (s == null)
// return null;
// StringBuilder sb = new StringBuilder();
// for (int i = 0; i < s.length(); i++) {
// if (String.valueOf(s.charAt(i)).equals(" ")) {
// sb.append("%20");
// } else {
// sb.append(s.charAt(i));
// }
// }
// return String.valueOf(sb);
}
}
Go实现
// 遍历添加
func replaceSpace(s string) string {
b := []byte(s)
result := make([]byte, 0)
for i := 0; i < len(b); i++ {
if b[i] == ' ' {
result = append(result, []byte("%20")...)
} else {
result = append(result, b[i])
}
}
return string(result)
}
方法二:字符数组
由于每次替换从 1 个字符变成 3 个字符,使用字符数组可方便地进行替换。建立字符数组地长度为 s 的长度的 3 倍,这样可保证字符数组可以容纳所有替换后的字符。
-
获得 s 的长度 length
-
创建字符数组 array,其长度为 length * 3
-
初始化 size 为 0,size 表示替换后的字符串的长度
-
从左到右遍历字符串 s
- 获得 s 的当前字符 c
- 如果字符 c 是空格,则令 array[size] = '%',array[size + 1] = '2',array[size + 2] = '0',并将 size 的值加 3
- 如果字符 c 不是空格,则令 array[size] = c,并将 size 的值加 1
-
遍历结束之后,size 的值等于替换后的字符串的长度,从 array 的前 size 个字符创建新字符串,并返回新字符串
复杂性分析
- 时间复杂度:O(n)。遍历字符串 s 一遍。
- 空间复杂度:O(n)。额外创建字符数组,长度为 s 的长度的 3 倍。
/**
* 方法二:字符数组
* @param s
* @return
*/
public String replaceSpace2(String s) {
int length = s.length();
char[] array = new char[length * 3];
int size = 0;
for (int i = 0; i < length; i++) {
char c = s.charAt(i);
if (c == ' ') {
array[size++] = '%';
array[size++] = '2';
array[size++] = '0';
} else {
array[size++] = c;
}
}
String newStr = new String(array, 0, size);
return newStr;
}
还有一种解法,这个看看就好哈哈
public String replaceSpace(String s) { return s.replace(" ","%20"); }
用Go实现
// 原地修改
func replaceSpace(s string) string {
b := []byte(s)
length := len(b)
spaceCount := 0
// 计算空格数量
for _, v := range b {
if v == ' ' {
spaceCount++
}
}
// 扩展原有切片
resizeCount := spaceCount * 2
tmp := make([]byte, resizeCount)
b = append(b, tmp...)
i := length - 1
j := len(b) - 1
for i >= 0 {
if b[i] != ' ' {
b[j] = b[i]
i--
j--
} else {
b[j] = '0'
b[j-1] = '2'
b[j-2] = '%'
i--
j = j - 3
}
}
return string(b)
}
思路:栈
采用栈的方式倒序写入遍历,虽然效率不是很高,但是也算提供另外一种解题思路吧。
倒序遍历字符串数组, 遇到' ',将'0','2','%'压入栈,若为正常字符直接入栈,随后依次出栈+拼串,完成操作。
class Solution {
public String replaceSpace(String s) {
char[] chars = s.toCharArray();
Stack<Character> stack = new Stack<>();
for (int i = s.length() - 1; i >= 0; i--) {
if (chars[i] == ' ') {
stack.push('0');
stack.push('2');
stack.push('%');
} else {
stack.push(chars[i]);
}
}
String s1 = "";
while (!stack.isEmpty()) {
Character pop = stack.pop();
s1 += pop;
}
return s1;
}
}
参考链接: