持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情
请实现一个函数,把字符串 s 中的每个空格替换成 "%20"。
示例 1:
输入: s = "We are happy."
输出: "We%20are%20happy."
限制:
0 <= s 的长度 <= 10000
解题思路:暴力解法
遍历字符串,使用一个新的对象,复制 str,复制的过程对其判断,是空格则替换,否则直接复制,类似于数组复制
代码:(JAVA实现)
public String replaceSpace(String s) {
if (s.length() == 0 || s == null) {
return s;
}
int start = 0;
//选用 StringBuilder 单线程使用,比较快,选不选都行
StringBuffer res = new StringBuffer();
//使用res来复制str,遇到空格就是替换,否则直接复制
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == ' ') {
res.append(s.substring(start,i));
res.append("%20");
start = i + 1;
}
}
res.append(s.substring(start,s.length()));
return res.toString();
}
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(1)
提交结果
解题思路:双指针
第一种虽然也能通过,但如果想把这道题做到极致的话,不使用额外的辅助空间,就需要使用双指针来实现了
首先我们需要先将数组扩充到可以放下“%20“之后的大小
然后再从后向前遍历字符串,也就是双指针,具体思路
i指向扩充数组的末尾,j指向原始数组的末尾
这里使用从后向前字符串,而不是从前向后遍历字符串的原因是
- 从前向后遍历字符串,每次添加新元素时,都需要将新元素后的元素向后移动,时间复杂度较高。而从后向前比遍历,则避免了这种情况的出现
- 不用申请新数组空间
代码:(Java实现)
public String replaceSpace(String s) {
if (s.length() == 0 || s == null) {
return s;
}
//扩充数组大小
StringBuffer res = new StringBuffer();
for (int i = 0; i < s.length();i++) {
if (s.charAt(i) == ' ') {
res.append(" ");
}
}
//若数组没有空格则直接返回
if (res.length() == 0) {
return s;
}
//指向原始数组的末尾
int left = s.length()-1;
//将原始数组数组扩充空间
s += res.toString();
//指向扩充数组的末尾
int right = s.length()-1;
char[] chars = s.toCharArray();
while (left >= 0) {
if (chars[left] == ' ') {
chars[right--] = '0';
chars[right--] = '2';
chars[right] = '%';
}else {
chars[right] = chars[left];
}
left--;
right--;
}
return new String(chars);
}
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(1)