剑指Offer 05.替换空格
- 1 题目
- 2 思路--双指针法
- 3 代码
- 3.1 C++版本
- 3.2 C版本
- 3.3 Java版本
- 3.4 Python3版本
- 3.5 JavaScript版本
- 4 总结
1 题目
题源链接
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例 1:
输入:s = “We are happy.”
输出:“We%20are%20happy.”
限制:
0 <= s 的长度 <= 10000
2 思路–双指针法
首先扩充数组到每个空格替换成"%20"之后的大小。
然后从后向前替换空格
,也就是双指针法,过程如下:
i指向新长度的末尾,j指向旧长度的末尾。
动画演示
其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。
这么做有两个好处:
- 不用申请新数组。
- 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
3 代码
3.1 C++版本
class Solution {
public:
string replaceSpace(string s) { //双指针法
int cnt = 0; //记录空格个数
int lenOld = s.size();
for (int i = 0; i < s.size(); i++)
if (s[i] == ' ')
cnt++;
// 扩充s为空格替换成%20之后的大小
s.resize(s.size() + cnt * 2);
int lenNew = s.size();
for (int i = lenNew - 1, j = lenOld - 1; j < i; i--, j--) {
if (s[j] != ' ')
s[i] = s[j];
else {
s[i--] = '0';
s[i--] = '2';
s[i] = '%';
}
}
return s;
}
};
3.2 C版本
char* replaceSpace(char* s){
//统计空格数量
int count = 0;
int len = strlen(s);
for (int i = 0; i < len; i++) {
if (s[i] == ' ') {
count++;
}
}
//为新数组分配空间
int newLen = len + count * 2;
char* result = malloc(sizeof(char) * newLen + 1);
//填充新数组并替换空格
for (int i = len - 1, j = newLen - 1; i >= 0; i--, j--) {
if (s[i] != ' ') {
result[j] = s[i];
} else {
result[j--] = '0';
result[j--] = '2';
result[j] = '%';
}
}
result[newLen] = '\0';
return result;
}
3.3 Java版本
public String replaceSpace(String s) {
if(s == null || s.length() == 0){
return s;
}
//扩充空间,空格数量2倍
StringBuilder str = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if(s.charAt(i) == ' '){
str.append(" ");
}
}
//若是没有空格直接返回
if(str.length() == 0){
return s;
}
//有空格情况 定义两个指针
int left = s.length() - 1;//左指针:指向原始字符串最后一个位置
s += str.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);
}
3.4 Python3版本
class Solution:
def replaceSpace(self, s: str) -> str:
# method 1 - Very rude
return "%20".join(s.split(" "))
# method 2 - Reverse the s when counting in for loop, then update from the end.
n = len(s)
for e, i in enumerate(s[::-1]):
print(i, e)
if i == " ":
s = s[: n - (e + 1)] + "%20" + s[n - e:]
print("")
return s
3.5 JavaScript版本
/**
* @param {string} s
* @return {string}
*/
var replaceSpace = function(s) {
// 字符串转为数组
const strArr = Array.from(s);
let count = 0;
// 计算空格数量
for(let i = 0; i < strArr.length; i++) {
if (strArr[i] === ' ') {
count++;
}
}
let left = strArr.length - 1;
let right = strArr.length + count * 2 - 1;
while(left >= 0) {
if (strArr[left] === ' ') {
strArr[right--] = '0';
strArr[right--] = '2';
strArr[right--] = '%';
left--;
} else {
strArr[right--] = strArr[left--];
}
}
// 数组转字符串
return strArr.join('');
};
4 总结
- 时间复杂度:O(n)
- 空间复杂度:O(1)
By – Suki 2023/2/3