题目描述
在 Python 和 Java 等语言中,字符串都被设计成不可变的类型,即无法直接在原来的字符串上做替换,需要新建一个空字符串实现。
时间复杂度 O(n): 遍历字符数组需要 O(n),每轮添加(修改)字符操作需要 O(1) ;
空间复杂度 O(n) : Python 新建的 list 和 Java 新建的 StringBuilder 都使用了线性大小的额外空间。
Python
class Solution(object):
def replaceSpace(self, s):
"""
:type s: str
:rtype: str
"""
res = []
for c in s:
if c == ' ':
res.append('%20')
else:
res.append(c)
return ''.join(res) # 将列表 res 转化为字符串并返回
Java
class Solution {
public String replaceSpace(String s) {
StringBuilder res = new StringBuilder();
for (char c: s.toCharArray()){ // 或 for (Character c: s.toCharArray())
if (c == ' ')
res.append("%20");
else
res.append(c);
}
return res.toString();
}
}
《剑指offer》中的解法
实际上,在《剑指offer》中,关于这套题目,作者的本意是在原字符数组上进行扩容和替换操作,并且是从后往前进行替换,从而减少了待替换的空格后面所有字符的搬移次数,所有的字符都只需要复制(移动)一次,因此时间复杂度为 O(n)。
由于在Java中,字符串类型不允许原地修改,我们通过数组来实现这个思路。
class Solution {
public String replaceSpace(String s) {
// 统计出字符串中空格的数目
int count = 0;
for (int i=0; i< s.length(); i++){
if (s.charAt(i) == ' '){ // charAt()方法用于返回指定索引处的字符
count++;
}
}
// 新建一个字符数组,长度为原来字符串的长度+空格数⽬*2
char[] ch = new char[s.length()+ count*2];
// 定义两个指针,分别指向原始字符串的末尾、替换之后的字符串的末尾
int p1 = s.length() -1;
int p2 = ch.length -1;
while (p1 >=0 && p2 >= 0){
// 若碰到空格,把p1向前移动一格,在p2之前插入字符串“%20”,然后把p2向前移动三格
if (s.charAt(p1) == ' '){
ch[p2] = '0';
ch[p2-1] = '2';
ch[p2-2] = '%';
p1 -= 1;
p2 -= 3;
}
// 否则,逐个把p1指向的字符复制到P2指向的位置
else{
ch[p2] = s.charAt(p1);
p1 -= 1;
p2 -= 1;
}
}
/*
char数组转成字符串的方法有两种:
一种是直接将字符数组作为参数,通过new()构造String对象;
另一种是使用String的valueOf()方法
*/
// return new String(ch);
return String.valueOf(ch);
}
}
时间复杂度 O(n)
空间复杂度 O(n) : 创建一个字符数组需要的额外空间。
参考
https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/solution/mian-shi-ti-05-ti-huan-kong-ge-ji-jian-qing-xi-tu-/