Go 中的旋转数组

gyu*_*asf 6 go slice

这是 LeetCode 问题:189. 旋转数组

给定一个数组,将数组向右旋转 k 步,其中 k 为非负数。

示例1:

输入:[1,2,3,4,5,6,7] 且 k = 3
输出:[5,6,7,1,2,3,4]

这是我的解决方案:

func rotate(nums []int, k int)  {
    k = k % len(nums)
    nums = append(nums[k:],nums[0:k]...)
    fmt.Println(nums)
}
Run Code Online (Sandbox Code Playgroud)

这是一个简单的算法,但它不起作用。

我是围棋新手。我想nums是按值传递的,并且更改nums不会影响真实的nums.

我怎样才能做到这一点?

pet*_*rSO 8

在 Go 中,所有参数都是按值传递的。

Go 切片在运行时由切片描述符表示:

type slice struct {
    array unsafe.Pointer
    len   int
    cap   int
}
Run Code Online (Sandbox Code Playgroud)

如果更改函数中的任何切片描述符值,则通常通过返回更改的切片描述符来传达更改。


您的rotate函数将切片指针的值更改num为底层数组和切片容量,因此返回num

例如,在我修复了你的rotate算法中的错误之后,

package main

import "fmt"

func rotate(nums []int, k int) []int {
    if k < 0 || len(nums) == 0 {
        return nums
    }

    fmt.Printf("nums %p array %p len %d cap %d slice %v\n", &nums, &nums[0], len(nums), cap(nums), nums)

    r := len(nums) - k%len(nums)
    nums = append(nums[r:], nums[:r]...)

    fmt.Printf("nums %p array %p len %d cap %d slice %v\n", &nums, &nums[0], len(nums), cap(nums), nums)

    return nums
}

func main() {
    nums := []int{1, 2, 3, 4, 5, 6, 7}

    fmt.Printf("nums %p array %p len %d cap %d slice %v\n", &nums, &nums[0], len(nums), cap(nums), nums)

    nums = rotate(nums, 3)

    fmt.Printf("nums %p array %p len %d cap %d slice %v\n", &nums, &nums[0], len(nums), cap(nums), nums)
}
Run Code Online (Sandbox Code Playgroud)

输出:

nums 0xc00000a080 array 0xc00001a1c0 len 7 cap 7 slice [1 2 3 4 5 6 7]
nums 0xc00000a0c0 array 0xc00001a1c0 len 7 cap 7 slice [1 2 3 4 5 6 7]
nums 0xc00000a0c0 array 0xc00001a240 len 7 cap 8 slice [5 6 7 1 2 3 4]
nums 0xc00000a080 array 0xc00001a240 len 7 cap 8 slice [5 6 7 1 2 3 4]
Run Code Online (Sandbox Code Playgroud)

参考:Go 博客:Go Slices:用法和内部结构