题目链接:541. 反转字符串 II
题目:
给定一个字符串 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个字符的前k的字符,我写了一堆逻辑代码以及搞了一个遍历数组的指针 i,来统计2k,再搞了一个 j 来统计前k个字符。
其实在遍历字符串的过程中,只要让 i += (2 * k)
,i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。因为要找的也就是每2 * k 区间的起点,这样写,程序会高效很多。
所以当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。
代码(c++):
class Solution {
public:
//交换2k字符中的前k个字符
void reverse(string& s, int left, int right) {
while (left < right) {
swap(s[left++], s[right--]);
}
}
string reverseStr(string s, int k) {
//每次i向前移动2k个字符
for (int i = 0; i < s.length(); i += 2 * k) {
//如果i往前有不少于k个字符,则反转i~i + k - 1之间的字符
if (i + k <= s.length()) {
reverse(s, i, i + k - 1);
continue;
}
//如果i往前少于k个字符,则反转i~s.length() - 1之间的字符
reverse(s, i, s.length() - 1);
}
return s;
}
};