小知识,大挑战!本文正在参与「程序员必备小知识」创作活动
原题链接
题目描述
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
- 如果剩余字符少于 k 个,则将剩余字符全部反转。
- 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
测试用例
示例 1:
输入:s = "abcdefg", k = 2
输出:"bacdfeg"
示例 2:
输入:s = "abcd", k = 2
输出:"bacd"
参数限制
- 1 <= s.length <= 104
- s 仅由小写英文组成
- 1 <= k <= 104
分析
题目要求可以简化为,将字符按照 2k 的长度进行分组,最后一组的长度可能不足 2k
对分好组后的子字符串,前面 k 个字符需要反转,后面 k 个保持不变
代码
使用一个栈来逐个接受字符,等 stack.length == 2k 时,开始按要求反转
var reverseStr = function(s, k) {
let arr = [],
stack = [];
for (let i = 0; i < s.length; i++) {
stack.push(s.charAt(i));
if (stack.length == 2 * k) {
arr.push(...stack.slice(0, k).reverse());
arr.push(...stack.slice(k, 2 * k));
stack = [];
}
}
if (stack.length != 0) {
arr.push(...stack.slice(0, k).reverse());
arr.push(...stack.slice(k, 2 * k));
}
return arr.join('');
};
解法 2
采用分组的思路, 在外层标记当前小组的字符是否需要反转,然后直接进行字符串拼接
var reverseStr = function(s, k) {
let n = Math.ceil(s.length / k);
let flag = true;
let str = '';
for (let i = 0; i < n; i++) {
let m = i * k;
if (flag) {
for (let j = k - 1; j >= 0; j--) {
str += s.charAt(m + j);
}
} else {
for (let j = 0; j < k; j++) {
str += s.charAt(m + j);
}
}
flag = !flag;
}
return str;
};
解法 3
直接将字符串转化为数组,然后在数组上做原地替换,这种方案占用的内存最小,同时,也是效率最高的
var reverseStr = function(s, k) {
s = s.split('')
let n = Math.ceil(s.length / k);
for (let i = 0; i < n; i += 2) {
let l = i * k,
r = Math.min(s.length-1, (i + 1) * k-1);
while (l < r) {
let temp = s[l];
s[l++] = s[r];
s[r--] = temp;
}
}
return s.join('');
};
今天的力扣刷题就分享到这里,感谢大家的阅读~