77. 组合
题目链接
leetcode.cn/problems/co…
文章链接
programmercarl.com/0077.%E7%BB…
视频链接
www.bilibili.com/video/BV1ti…
剪枝操作:
www.bilibili.com/video/BV1wi…
看到题目的第一想法
我看到这道题目的第一想法就是用for循环嵌套,用暴力的方法去解这道题,但是我很快就发现这道题用暴力的方法没有用,因为组合数是k,k是一个变量,k为2,有两层for循环,k为3,有三层for循环。如果我们用暴力去做,则没法控制循环层数,然后我就不知道该怎么去做了。
看完代码随想录之后的想法
看完了才知道用回溯来做这道题,用递归的次数来控制循环的层数,下面附上我的go语言代码:
var result [][]int
func combine(n int, k int) [][]int {
result = [][]int{}
backTracking(n, k, 1, []int{})
return result
}
func backTracking(n, k, startIndex int, track []int) {
if len(track) == k {
temp := make([]int, k)
copy(temp, track)
result = append(result, temp)
}
for i := startIndex; i <= n; i++ {
track = append(track, i)
backTracking(n, k, i+1, track)
track = track[:len(track)-1]
}
}
这里在for循环里就有回溯的过程了,好不容易append进去的元素,在递归过后又弹出来了,回溯在这里体现了出来。上面的代码还可以进行优化,称之为剪枝,剪枝过后的代码为:
var res [][]int
func combine(n int, k int) [][]int {
res=[][]int{}
if n <= 0 || k <= 0 || k > n {
return res
}
backtrack(n, k, 1, []int{})
return res
}
func backtrack(n,k,start int,track []int){
if len(track)==k{
temp:=make([]int,k)
copy(temp,track)
res=append(res,temp)
}
if len(track)+n-start+1 < k {
return
}
for i:=start;i<=n;i++{
track=append(track,i)
backtrack(n,k,i+1,track)
track=track[:len(track)-1]
}
}
实现过程中遇到的困难
困难就是代码不熟悉,回溯算法理解起来有难度,希望以后能更加熟练。
今日收获
知道了排列组合是用回溯来实现的。