算法训练 Day 24

LeetCode 77. 组合

题目链接:77. 组合

思路:在这里插入图片描述

Python版本:

class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        def backt(path, start):
            if len(path)==k:
                res.append(path[:])
                return
            
            for i in range(start, n+1):
                path.append(i)
                backt(path, i+1)
                path.pop()

        res = []
        backt([], 1)
        return res

go版本:

var res [][]int

func combine(n int, k int) [][]int {
    // 不初始化res就会出bug
    res = [][]int{}
    backt([]int{}, 1, k, n)
    return res
}

func backt(path []int, start, k, n int) {
    if len(path)==k {
        tmp := make([]int, k)
        copy(tmp, path)
        res = append(res, tmp)
        return
    }
    // 加入剪枝:如果后续所有数字都添加上都不满足len(path)==k时, 则直接结束递归
    if len(path)+n-start+1 < k {
        return
    }
    for i:=start; i<=n; i++ {
        path = append(path, i)
        backt(path, i+1, k, n)
        path = path[:len(path)-1]
    }
}

关于不初始化res会出现解答错误的问题,具体原因就是LeetCode的判定规则——每道题目你提交之后所用的测试用例共享全局变量,LeetCode提交代码之后是在服务器跑的,多组样例一起传参,但全局变量只会初始化一次,这就是这道题res放在全局变量会出现解答错误的原因(详见此篇博客)。

避免错误有两种办法:一是在combine函数开始位置初始化一下res数组;二是在combine函数开始位置设置一个defer,其实跟初始化一下res数组的思想是一样的,都是避免这个全局变量在运行下一个测试用例的时候还带着上一个用例的数据。

引申:
关于golang语言的切片初始化的问题,运行以下代码进行测试。

package main

import (
	"fmt"
)

var res [][]int

func main() {
	
	fmt.Println(res)

	fmt.Println(res == nil)
	
	fmt.Println(len(res))
	
	fmt.Printf("%p\n", &res)
}

输出如下:

[]
true    
0       
0x956450

通过代码运行结果,我们可以得出以下两条结论:

  1. golang可以对切片赋予默认值,切片的默认值是nil;
  2. 即使没有进行初始化的切片(被赋予默认值nil的切片),也是拥有一个地址的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值