Значение было изменено в методе - PullRequest
0 голосов
/ 26 февраля 2020

Я решаю проблему в leetcode, используя рекурсию. Но значение, используемое в качестве параметра, изменяется в методе.

package main

import "fmt"

func makeCmbs(cmbs [][]int, nums []int, remains []int, k int) [][]int {
    fmt.Println("==", cmbs, nums, remains, k) // (2)
    if k == 0 {
        cmbs = append(cmbs, nums)
        fmt.Println("!", nums, cmbs)
        return cmbs
    }

    for i, num := range remains {
        fmt.Printf("-[%d] num:%d cmbs:%v remains:%v\n", i, num, cmbs, remains) // (1) cmbs here is [[1,2,3,4]]
        cmbs = makeCmbs(cmbs, append(nums, num), remains[i+1:], k-1) // cmbs in makeCmbs method is [[1,2,3,5]] ???
        fmt.Printf("+[%d] num:%d cmbs:%v\n", i, num, cmbs)
    }

    return cmbs
}

func combine(n int, k int) [][]int {
    remains := make([]int, n)
    for i := 0; i < n; i++ {
        remains[i] = i + 1
    }

    return makeCmbs([][]int{}, []int{}, remains, k)
}

func main() {
    combine(5, 4)
}

Ниже указано начало вывода.

== [] [] [1 2 3 4 5] 4
-[0] num:1 cmbs:[] remains:[1 2 3 4 5]
== [] [1] [2 3 4 5] 3
-[0] num:2 cmbs:[] remains:[2 3 4 5]
== [] [1 2] [3 4 5] 2
-[0] num:3 cmbs:[] remains:[3 4 5]
== [] [1 2 3] [4 5] 1
-[0] num:4 cmbs:[] remains:[4 5]
== [] [1 2 3 4] [5] 0
! [1 2 3 4] [[1 2 3 4]]
+[0] num:4 cmbs:[[1 2 3 4]]
-[1] num:5 cmbs:[[1 2 3 4]] remains:[4 5] <---- cmbs is [[1 2 3 4]]
== [[1 2 3 5]] [1 2 3 5] [] 0             <---- why [[1 2 3 5]] ???

Как видно из последних двух строк, cmbs [[1 2 3 4]] стал [[1 2 3 5]]. Кто-нибудь может дать мне понять, почему значение cmbs изменяется в методе makeCmbs?

1 Ответ

1 голос
/ 26 февраля 2020

Давайте начнем с рекурсии последней рекурсивной l oop вызова makeCmbs

cmbs = makeCmbs(cmbs, append(nums, num), remains[i+1:], k-1)

As остается [i + 1:], где значение i в конце l oop будет самым высоким то есть

i = len(remains-1)

Таким образом, это означает, что i+1 на два (2) больше, чем len(remains-1), поэтому remain[i+1] будет пустым array ([]) для первых двух последних раундов повторного получения.

Вот как это работает. Я надеюсь, что добрался до творческой высоты этой проблемы.

ОБНОВЛЕНИЕ:

Впервые, когда k=0

start of function: num:[1 2 3 4] cmbs:[] remains:[5], k:0

Итак, if k=0 условие true

    if k == 0 {
        cmbs = append(cmbs, nums)
        fmt.Printf("in side if: num:%d cmbs:%v k:%v\n", nums, cmbs, k)
        return cmbs
    }

, то есть первое возвращение рекурсии

как cmbs = [] и nums = [1 2 3 4]

cmbs = append(cmbs, nums)

Теперь перенастроенное значение равно cmb, если условие [[1 2 3 4]] для l oop эта строка

cmbs = makeCmbs(cmbs, append(nums, num), remains[i+1:], k-1)

и здесь l oop заканчивается, поэтому она также возвращает то же самое

 [[1 2 3 4]]

Но в до этого к рекурсии добавлялись nums + num + num, то есть [1 2 3 5], поэтому, когда он возвращается во второй последней рекурсии, то же самое для l oop вызовов cmbs удерживают [1 2 3 5].

It Это действительно сложный вопрос, но его легко решить с помощью отладчика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...