541. 反转字符串 II
func reverseStr(s string, k int) string {
ss := []byte(s)
l := len(ss)
rem := l % (2 * k)
num := l / (2 * k)
var temp byte
if num == 0 { //l小于2k
if l <= k { //直接反转全部
left := 0
right := l - 1
for left < right {
temp = s[left]
ss[left] = ss[right]
ss[right] = temp
left++
right--
}
} else { //只反转前k个
left := 0
right := k - 1
for left < right {
temp = s[left]
ss[left] = ss[right]
ss[right] = temp
left++
right--
}
}
} else { //l大于2k
if rem >= k { //剩余的>=k
for i := 0; i < num+1; i++ { //此处细节num+1
left := i * 2 * k
right := i*2*k + k - 1
for left < right {
temp = s[left]
ss[left] = ss[right]
ss[right] = temp
left++
right--
}
}
} else if rem < k { //剩余的<k
for i := 0; i < num; i++ {
left := i * 2 * k
right := i*2*k + k - 1
for left < right {
temp = s[left]
ss[left] = ss[right]
ss[right] = temp
left++
right--
}
}
left := l - rem
right := l - 1
var temp byte
for left < right {
temp = ss[left]
ss[left] = ss[right]
ss[right] = temp
left++
right--
}
}
}
return string(ss)
}
具体思路很简单,就是分类有点多,核心的反转代码和344. 反转字符串一样,只是修改一下参数的初始值
细节
总长度l大于2k,剩余的>=k,这种情况时,
nums+1
,多循环一轮,把剩余的前k个再反转一下
这样写起来代码比较长,反转那一部分核心代码是重复的,只是
left
,right
初始值不同,可以拿出来写一个函数,然后调用。
func reverseStr(s string, k int) string {
ss := []byte(s)
length := len(s)
for i := 0; i < length; i += 2 * k {
// 1. 每隔 2k 个字符的前 k 个字符进行反转
// 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
if i+k <= length {
reverse(ss[i : i+k])
} else {
reverse(ss[i:length])
}
}
return string(ss)
}
func reverse(b []byte) {
left := 0
right := len(b) - 1
for left < right {
b[left], b[right] = b[right], b[left]
left++
right--
}
}