mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-07 15:45:40 +08:00
update 0077.组合:更新python 和 go 代码
This commit is contained in:
@ -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叉树),用树形结构来理解回溯就容易多了**。
|
||||||
|
|
||||||
那么我把组合问题抽象为如下树形结构:
|
那么我把组合问题抽象为如下树形结构:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
可以看出这个棵树,一开始集合是 1,2,3,4, 从左向右取数,取过的数,不在重复取。
|
可以看出这棵树,一开始集合是 1,2,3,4, 从左向右取数,取过的数,不再重复取。
|
||||||
|
|
||||||
第一次取1,集合变为2,3,4 ,因为k为2,我们只需要再取一个数就可以了,分别取2,3,4,得到集合[1,2] [1,3] [1,4],以此类推。
|
第一次取1,集合变为2,3,4 ,因为k为2,我们只需要再取一个数就可以了,分别取2,3,4,得到集合[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
|
||||||
|
Reference in New Issue
Block a user