问题描述:
Given a string s and an integer k, reverse the first k characters for every 2k characters counting from the start of the string.
If there are fewer than k characters left, reverse all of them. If there are less than 2k but greater than or equal to k characters, then reverse the first k characters and left the other as original.
每隔2k个字符翻转区间内前k个字符(其后k个字符不动)。如果区间内(最后一个区间)不足k个字符,则全部反转。
思路:
每隔2k个字符反转前k个字符。**设计算法时先不考虑特殊情况,即所剩的字符不是一个2k长度的的满区间的情况这样的设计思路会给予像我这样的初学者方便。和解大多数字符串题目一样,我们循环的时候从0开始,至最后,但这次步长为2k。在循环内部,我们要做两件事:第一件事是反转(即逆序输出)前k个字符,所以内层循环的循环变量要从i+k-1(含)**到i(含)递减,已达到倒序输出前k个字符的效果;第二件事是照搬(正序输出)后k个字符,所以循环变量要从i+k(含)**到i+2k-1(含)**递增,以达到正序输出的目的。
然后我们再考虑特殊情况,即在最后一个区间内,我们的区间不足2k个元素。情况还可以细分,如果不够k个,就把剩下的统统反过来;如果够k个但不够2k个,我们依然只反转前k个,剩下的照搬。因为特殊情况只是在最后一个区间出现,我们可以把需要用到上界的地方和s.length()-1作比较取较小者 。需要用到上界的地方在上一段中用黑体字标记了。
代码如下:
class Solution {
public String reverseStr(String s, int k) {
StringBuilder sb = new StringBuilder();
for(int i=0; i<s.length(); i+=2*k){
for(int j=Math.min(s.length()-1, i+k-1); j>=i; j--){
sb.append(s.charAt(j));
}
for(int l=i+k; l<=Math.min(s.length()-1, i+2*k-1); l++){
sb.append(s.charAt(l));
}
}
return sb.toString();
}
}
时间复杂度:O(n)