Повернуть массив в Go - PullRequest
       9

Повернуть массив в Go

0 голосов
/ 13 июня 2018

Это проблема LeetCode: 189.Rotate Array :

Для данного массива поверните массив вправо на 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)
}

Это простой алгоритм, но он не работает.

Я новичок в Go.Я предполагаю, что nums передается по значению, и изменения в nums не влияют на действительное nums.

Как я могу получить это право?

Ответы [ 2 ]

0 голосов
/ 14 июня 2018

Это не работает, потому что []byte - это фрагмент, который является своего рода «указателем на массив».Выполнение:

func f(v []T) {
  v = ... //
}

не будет иметь никакого наблюдаемого эффекта для звонящего.Предполагая, что ваш append путь правильный (на самом деле не проверял), вы можете сделать что-то вроде этого:

func rotate(nums []int, k int) {
    k = k % len(nums)
    temp := append(nums[k:], nums[0:k]...)
    copy(nums, temp) // this actually writes to where nums points to
}

func main() {
    nums := []int{1,2,3,4,5,6,7}
    rotate(nums ,3)
    fmt.Println(nums)
}
0 голосов
/ 13 июня 2018

В Go все аргументы передаются по значению.

Срез Go представлен во время выполнения дескриптором слайса:

type slice struct {
    array unsafe.Pointer
    len   int
    cap   int
}

Если вы измените любое из значений дескриптора слайса вЗатем функция сообщает об изменении, обычно возвращая измененный дескриптор слайса.


Ваша 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)
}

Вывод:

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]

Ссылка: Блог Go: Go Slices: использование и внутреннее оборудование

...