超时版:
// 5957. 向字符串添加空格
// 超时版
class Solution {
public:
string addSpaces(string s, vector<int>& spaces) {
// 返回结果
string ans = s;
// 每次插入时的空字符串
string EMPTY_STR(" ");
// 这里从后往前遍历空格的位置,可以避免,再次计算,保证整个插入过程spaces中的值都可以直接使用
for(int i = spaces.size() - 1; i >= 0; i--){
// 在i的前面插入" "
ans.insert(spaces[i], EMPTY_STR);
}
return ans;
}
};
升级版:
在超时版中有一个显然的问题时,每次插入会导致,某个位置的数组元素向后移动,而且这种影响会随着数组的大小和插入的位置变化,整体来说每一次插入时,时间复杂度为O(n),如果需要需要插入的次数非常多,这样造成的性能问题就回很会明显。
那能不能减少这样的移动次数,其实好的一点是我们已经知道了需要插入的位置和次数,所以我们可以这样做,来减少移动的次数。
具体的做法是:
1.先根据 需要插入的次数 和 原字符串的长度 确实最后的结果的长度
2.在初始化结果字符串时我们可以先将里面的每个位置设为" "
3.有了2的基础我们就将怎样插入空格的问题转换为了怎样插入字母的问题
// 5957. 向字符串添加空格
// 优化版
class Solution {
public:
string addSpaces(string s, vector<int>& spaces) {
// 1.先根据 需要插入的次数 和 原字符串的长度 确实最后的结果的长度
// 2.在初始化结果字符串时我们可以先将里面的每个位置设为" "
string ans(s.size() + spaces.size(), ' ');
// spaces的当前下标
int indexSpa = 0;
// s的下标相对于ans来说的偏移量
int offset = 0;
// 3.将s中的字符填充到ans中
for(int i = 0; i < s.size(); i++){
// 如果当前仍然有空格的位置,且当前即为空格应该出现的位置
if(indexSpa < spaces.size() && i == spaces[indexSpa]){
// 将该位置记为空格的位置
offset++;
// 移动到下一个空格的位置
indexSpa++;
}
// 将s中的元素移动向ans的对应位置
ans[offset + i] = s[i];
}
return ans;
}
};