3 回答
TA贡献1875条经验 获得超5个赞
一次旋转切片一个位置,并重复以获得所需的总旋转量意味着需要的时间与旋转距离×切片长度成正比。通过将每个元素直接移动到其最终位置,您可以按与切片长度成比例的时间进行此操作。
这段代码比你所拥有的要复杂一些,你需要一个 GCD 函数来确定通过切片的次数:
func gcd(a, b int) int {
for b != 0 {
a, b = b, a % b
}
return a
}
func rotateL(a []int, i int) {
// Ensure the shift amount is less than the length of the array,
// and that it is positive.
i = i % len(a)
if i < 0 {
i += len(a)
}
for c := 0; c < gcd(i, len(a)); c++ {
t := a[c]
j := c
for {
k := j + i
// loop around if we go past the end of the slice
if k >= len(a) {
k -= len(a)
}
// end when we get to where we started
if k == c {
break
}
// move the element directly into its final position
a[j] = a[k]
j = k
}
a[j] = t
}
}
旋转大小的片升权由p位置相当于旋转它留下由升- p位置,这样你就可以简化您的rotateR使用功能rotateL:
func rotateR(a []int, i int) {
rotateL(a, len(a) - i)
}
TA贡献1825条经验 获得超6个赞
您的代码适合就地修改。
不明白你所说的按位运算是什么意思。也许这
package main
import "fmt"
func main() {
a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
fmt.Println(a)
rotateR(&a, 4)
fmt.Println(a)
rotateL(&a, 4)
fmt.Println(a)
}
func rotateL(a *[]int, i int) {
x, b := (*a)[:i], (*a)[i:]
*a = append(b, x...)
}
func rotateR(a *[]int, i int) {
x, b := (*a)[:(len(*a)-i)], (*a)[(len(*a)-i):]
*a = append(b, x...)
}
代码有效https://play.golang.org/p/0VtiRFQVl7
这在 Go 词汇中称为重新切片。权衡是在您的代码段中处理和循环与在此动态分配。这是您的选择,但在将 10000 个元素阵列移动一个位置的情况下,重新切片看起来便宜得多。
TA贡献1876条经验 获得超7个赞
我喜欢 Uvelichitel 解决方案,但如果您想要 O(n) 复杂度的模算术
package main
func main(){
s := []string{"1", "2", "3"}
rot := 5
fmt.Println("Before RotL", s)
fmt.Println("After RotL", rotL(rot, s))
fmt.Println("Before RotR", s)
fmt.Println("After RotR", rotR(rot,s))
}
func rotL(m int, arr []string) []string{
newArr := make([]string, len(arr))
for i, k := range arr{
newPos := (((i - m) % len(arr)) + len(arr)) % len(arr)
newArr[newPos] = k
}
return newArr
}
func rotR(m int, arr []string) []string{
newArr := make([]string, len(arr))
for i, k := range arr{
newPos := (i + m) % len(arr)
newArr[newPos] = k
}
return newArr
}
- 3 回答
- 0 关注
- 252 浏览
添加回答
举报