本题使用了双指针的方法,关键点在于扩展字符串长度从后向前更新字符串的思想。扩充字符串长度的好处是可以不用申请新数组。后序遍历的好处是从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动使得时间复杂度是O(n^2)的问题。
时间复杂度:O(n),空间复杂度:O(1)
思路:
- 扩充原始字符串的大小,使其能够容纳所有的空格替换为"%20"之后的字符串。
- 从后向前遍历字符串,其中 left 指针指向原字符串的尾部,right 指针指向新字符串的尾部。
- 如果是非空格字符,则将其复制到新字符串位置
- 如果是空格字符,则将其替换为"%20"。
- 返回 s。
代码:
class Solution {
public:
string replaceSpace(string s) {
int sOldLength = s.length();
int count = 0; // 统计空格的个数
for (int i = 0; i < sOldLength; i++) {
if (s[i] == ' ') {
count++;
}
}
// 扩充字符串s的大小,也就是每个空格替换成"%20"之后的大小
s.resize(sOldLength + count * 2);
int sNewLength = s.length();
// 从后先前将空格替换为"%20"
for (int left = sOldLength - 1, right = sNewLength - 1; left >= 0; left--, right --) {
if (s[left] == ' ') {
s[right--] = '0';
s[right--] = '2';
s[right] = '%';
} else {
s[right] = s[left];
}
}
return s;
}
};
方法二:本题还可以使用string STL中的find与replace接口进行替换。
时间复杂度:O(n),空间复杂度:O(1)
思路:
- 在while循环中反复使用find函数查找空格的位置,直到返回npos。
- 每个空格的位置使用replace函数替换为目标字符串“%20”。
代码:
class Solution {
public:
string replaceSpace(string s) {
int pos = 0;
while ((pos = s.find(' ')) != s.npos)
{
s.replace(pos, 1, "%20");
}
return s;
}
};