update 0077.组合:更新python 和 go 代码

This commit is contained in:
Yuhao Ju
2022-12-07 20:05:34 +08:00
committed by GitHub
parent 2575ff3b5c
commit 380fabb247

View File

@ -34,7 +34,7 @@
# 思路 # 思路
本题是回溯法的经典题目。 本题是回溯法的经典题目。
直接的解法当然是使用for循环例如示例中k为2很容易想到 用两个for循环这样就可以输出 和示例中一样的结果。 直接的解法当然是使用for循环例如示例中k为2很容易想到 用两个for循环这样就可以输出 和示例中一样的结果。
@ -82,13 +82,13 @@ for (int i = 1; i <= n; i++) {
如果脑洞模拟回溯搜索的过程,绝对可以让人窒息,所以需要抽象图形结构来进一步理解。 如果脑洞模拟回溯搜索的过程,绝对可以让人窒息,所以需要抽象图形结构来进一步理解。
**我们在[关于回溯算法,你该了解这些!](https://programmercarl.com/回溯算法理论基础.html)中说回溯法解决的问题都可以抽象为树形结构N叉树用树形结构来理解回溯就容易多了** **我们在[关于回溯算法,你该了解这些!](https://programmercarl.com/回溯算法理论基础.html)中说回溯法解决的问题都可以抽象为树形结构N叉树用树形结构来理解回溯就容易多了**
那么我把组合问题抽象为如下树形结构: 那么我把组合问题抽象为如下树形结构:
![77.组合](https://img-blog.csdnimg.cn/20201123195223940.png) ![77.组合](https://img-blog.csdnimg.cn/20201123195223940.png)
可以看出这棵树,一开始集合是 1234 从左向右取数,取过的数,不重复取。 可以看出这棵树,一开始集合是 1234 从左向右取数,取过的数,不重复取。
第一次取1集合变为234 因为k为2我们只需要再取一个数就可以了分别取234得到集合[1,2] [1,3] [1,4],以此类推。 第一次取1集合变为234 因为k为2我们只需要再取一个数就可以了分别取234得到集合[1,2] [1,3] [1,4],以此类推。
@ -120,7 +120,7 @@ vector<int> path; // 用来存放符合条件结果
其实不定义这两个全局变量也是可以的,把这两个变量放进递归函数的参数里,但函数里参数太多影响可读性,所以我定义全局变量了。 其实不定义这两个全局变量也是可以的,把这两个变量放进递归函数的参数里,但函数里参数太多影响可读性,所以我定义全局变量了。
函数里一定有两个参数既然是集合n里面取k那么n和k是两个int型的参数。 函数里一定有两个参数既然是集合n里面取k那么n和k是两个int型的参数。
然后还需要一个参数为int型变量startIndex这个参数用来记录本层递归的中集合从哪里开始遍历集合就是[1,...,n] )。 然后还需要一个参数为int型变量startIndex这个参数用来记录本层递归的中集合从哪里开始遍历集合就是[1,...,n] )。
@ -389,9 +389,8 @@ class Solution(object):
# 剪枝, 最后k - len(path)个节点直接构造结果,无需递归 # 剪枝, 最后k - len(path)个节点直接构造结果,无需递归
last_startidx = n - (k - len(path)) + 1 last_startidx = n - (k - len(path)) + 1
result.append(path + [idx for idx in range(last_startidx, n + 1)])
for x in range(startidx, last_startidx): for x in range(startidx, last_startidx + 1):
path.append(x) path.append(x)
backtracking(n, k, x + 1) # 递归 backtracking(n, k, x + 1) # 递归
path.pop() # 回溯 path.pop() # 回溯
@ -435,6 +434,36 @@ class Solution:
return res return res
``` ```
### Go
```Go
var (
path []int
res [][]int
)
func combine(n int, k int) [][]int {
path, res = make([]int, 0, k), make([][]int, 0)
dfs(n, k, 1)
return res
}
func dfs(n int, k int, start int) {
if len(path) == k { // 说明已经满足了k个数的要求
tmp := make([]int, k)
copy(tmp, path)
res = append(res, tmp)
return
}
for i := start; i <= n; i++ { // 从start开始不往回走避免出现重复组合
if n - i + 1 < k - len(path) { // 剪枝
break
}
path = append(path, i)
dfs(n, k, i+1)
path = path[:len(path)-1]
}
}
```
### javascript ### javascript
@ -481,63 +510,6 @@ function combine(n: number, k: number): number[][] {
}; };
``` ```
### Go
```Go
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]
}
}
```
剪枝:
```Go
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]
}
}
```
### Rust ### Rust
```Rust ```Rust