Medium
题目描述
给你一个下标从 0 开始的字符串 s 和一个下标从 0 开始的整数数组 spaces,该数组描述原字符串中需要添加空格的下标位置。每个空格都应该插入到给定下标对应字符的前面。
例如,给定 s = "EnjoyYourCoffee" 和 spaces = [5, 9],我们在下标 5 和 9 对应的字符 ‘Y’ 和 ‘C’ 前面分别放置空格。因此,我们得到 "Enjoy Your Coffee"。
返回添加空格后的修改字符串。
示例 1:
输入:s = "LeetcodeHelpsMeLearn", spaces = [8,13,15]
输出:"Leetcode Helps Me Learn"
解释:
下标 8、13 和 15 对应 "LeetcodeHelpsMeLearn" 中带下划线的字符。
然后我们在这些字符前面放置空格。
示例 2:
输入:s = "icodeinpython", spaces = [1,5,7,9]
输出:"i code in py thon"
解释:
下标 1、5、7 和 9 对应 "icodeinpython" 中带下划线的字符。
然后我们在这些字符前面放置空格。
示例 3:
输入:s = "spacing", spaces = [0,1,2,3,4,5,6]
输出:" s p a c i n g"
解释:
我们还可以在字符串的第一个字符前面放置空格。
提示:
1 <= s.length <= 3 * 10^5s仅包含小写和大写英文字母1 <= spaces.length <= 3 * 10^50 <= spaces[i] <= s.length - 1spaces中的所有值严格递增
解题思路
解题思路
这道题要求在指定位置插入空格,关键是要理解在某个下标前插入空格的含义。
方法分析:
暴力方法:遍历字符串,每次遇到需要插入空格的位置就插入,但这样会导致后续位置偏移,需要调整索引,效率较低。
双指针法(推荐):
- 使用一个指针
i遍历原字符串 - 使用另一个指针
j跟踪spaces数组 - 当
i等于spaces[j]时,先添加空格,再添加字符,然后移动j - 否则直接添加字符
- 使用一个指针
预计算长度法:先计算结果字符串的总长度(原长度 + 空格数),然后一次性分配空间填充。
实现要点:
- 由于
spaces数组已经排序,我们可以顺序处理 - 需要注意边界情况,如在字符串开头插入空格
- 使用
StringBuilder(C#)或类似高效字符串构建方式避免频繁内存分配
时间复杂度为 O(n + m),其中 n 是字符串长度,m 是空格数组长度。空间复杂度为 O(n + m)。
代码实现
class Solution {
public:
string addSpaces(string s, vector<int>& spaces) {
string result;
result.reserve(s.length() + spaces.size()); // 预分配空间
int j = 0; // spaces数组的指针
for (int i = 0; i < s.length(); i++) {
// 如果当前位置需要添加空格
if (j < spaces.size() && i == spaces[j]) {
result += ' ';
j++;
}
result += s[i];
}
return result;
}
};
class Solution:
def addSpaces(self, s: str, spaces: List[int]) -> str:
result = []
j = 0 # spaces数组的指针
for i in range(len(s)):
# 如果当前位置需要添加空格
if j < len(spaces) and i == spaces[j]:
result.append(' ')
j += 1
result.append(s[i])
return ''.join(result)
public class Solution {
public string AddSpaces(string s, int[] spaces) {
StringBuilder result = new StringBuilder(s.Length + spaces.Length);
int j = 0; // spaces数组的指针
for (int i = 0; i < s.Length; i++) {
// 如果当前位置需要添加空格
if (j < spaces.Length && i == spaces[j]) {
result.Append(' ');
j++;
}
result.Append(s[i]);
}
return result.ToString();
}
}
/**
* @param {string} s
* @param {number[]} spaces
* @return {string}
*/
var addSpaces = function(s, spaces) {
let result = [];
let spaceIndex = 0;
for (let i = 0; i < s.length; i++) {
if (spaceIndex < spaces.length && i === spaces[spaceIndex]) {
result.push(' ');
spaceIndex++;
}
result.push(s[i]);
}
return result.join('');
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n + m) | n为字符串长度,m为spaces数组长度,需要遍历字符串一次 |
| 空间复杂度 | O(n + m) | 结果字符串需要额外空间存储原字符串和空格 |