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 . l e n g t h ≤ 1 0 4 1 \leq s.length \leq 10^4 1≤s.length≤104
s
仅由小写英文组成- 1 ≤ k ≤ 1 0 4 1 \leq k \leq 10^4 1≤k≤104
解法一(相向双指针+模拟)
思路分析:
- 首先对于反转
k
个字符串,我们可以使用相向双指针来实现,可以单独编写一个反转函数reverseStr()
进行反转 - 然后根据题目的要求对情况做不同的处理;每次计算前对剩余字符做判断
- 若剩余字符大于
2k
则反转reverseStr(i, i+k-1, s)
- 若剩余字符小于
2k
大于k
则反转reverseStr(i, i+k-1, s)
- 若剩余字符少于
k
个,则将剩余字符全部反转,即reverseStr(i, s.length-1, s)
实现代码如下:
- 若剩余字符大于
class Solution {
public String reverseStr(String s, int k) {
int n = s.length(); // 字符串长度
if (n == 1) // 若字符串长度为1 则不需要反转
return s;
char[] str = s.toCharArray(); // 将字符串转化为字符数组
int i = 0; // 每次反转字符串的起始点
while (true) {
if (n-i >= 2*k) {
reverseStr(i, i+k-1, str);
i += 2*k;
} else if (n-i >= k) {
reverseStr(i, i+k-1, str);
break;
} else {
reverseStr(i, n-1, str);
break;
}
}
return new String(str);
}
// 反转字符串函数
public void reverseStr(int left, int right, char[] str) {
while (left < right) {
char ch = str[left];
str[left ++] = str[right];
str[right --] = ch;
}
}
}
提交结果如下:
解答成功:
执行耗时:0 ms,击败了100.00% 的Java用户
内存消耗:42.6 MB,击败了11.33% 的Java用户
复杂度分析:
- 时间复杂度:
O
(
m
⋅
k
)
O(m \cdot k)
O(m⋅k),其中
m
=
s
.
l
e
n
g
t
h
2
k
m = \frac{s.length}{2k}
m=2ks.length,即每次循环指针i都会增加
2k
的长度,因此寻找需要反转的字符串花费的时间复杂度为 s . l e n g t h 2 k \frac{s.length}{2k} 2ks.length,同时每次对寻找到的字符串进行反转花费的时间复杂度为 O ( k ) O(k) O(k),综合则时间复杂度为 O ( m ⋅ k ) O(m \cdot k) O(m⋅k) - 空间复杂度:
O
(
k
)
O(k)
O(k),不包括将字符串
s
转化为字符数组所花费的空间,即每次调用函数reverseStr()
花费空间复杂度为 O ( k ) O(k) O(k)