右旋字符串
题目:55. 右旋字符串(第八期模拟笔试) (kamacoder.com)
题目描述
字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。
例如,对于输入字符串 “abcdefg” 和整数 2,函数应该将其转换为 “fgabcde”。
输入描述
输入共包含两行,第一行为一个正整数 k,代表右旋转的位数。第二行为字符串 s,代表需要旋转的字符串。
输出描述
输出共一行,为进行了右旋转操作后的字符串。
输入示例
2
abcdefg
输出示例
fgabcde
提示信息
数据范围:
1 <= k < 10000,
1 <= s.length < 10000;
方法一:
先对字符数组进行扩容,然后利用双指针将前面的值付给后面,再在后面取多余的数赋值到前面。
package main
import "fmt"
func main() {
var s string
var k int
fmt.Scan(&k)
fmt.Scan(&s)
fmt.Println(rightHandSideN(s,k))
}
func rightHandSideN(s string, k int) string {
bytes := []byte(s)
Len := len(bytes)
exPlace := k % Len
newBytes := make([]byte, Len+exPlace)
r := len(newBytes) - 1
l := Len - 1
for l >= 0 {
newBytes[r] = bytes[l]
r--
l--
}
l = 0
r = Len
for exPlace != 0 {
newBytes[l] = newBytes[r]
l++
r++
exPlace--
}
return string(newBytes[:Len])
}
时间复杂度O(n),空间复杂度因为创建一个新字节数组所以为O(n)。
不用额外空间行不行呢,答案是可以的,就是反转再反转。
方法二:
利用反转,先将两个局部反转,在将整体反转。
package main
import "fmt"
func main() {
var s string
var k int
fmt.Scan(&k)
fmt.Scan(&s)
fmt.Println(rightHandSideN(s,k))
}
func rightHandSideN(s string, k int) string {
bytes := []byte(s)
Len := len(bytes)
idx := Len - k%Len
reverseRightHandSideN(bytes[:idx])
reverseRightHandSideN(bytes[idx:])
reverseRightHandSideN(bytes)
return string(bytes)
}
func reverseRightHandSideN(bytes []byte) {
l, r := 0, len(bytes)-1
for l < r {
bytes[l], bytes[r] = bytes[r], bytes[l]
l++
r--
}
}
当然你也可以先整体反转,再局部反转。快去试试吧。