Merge branch 'youngyangyang04:master' into master

This commit is contained in:
lmc1992
2021-09-17 22:05:51 -07:00
committed by GitHub
24 changed files with 686 additions and 67 deletions

View File

@@ -29,7 +29,7 @@
也可以直接看我的B站视频[带你学透回溯算法-组合问题对应力扣题目77.组合)](https://www.bilibili.com/video/BV1ti4y1L7cv#reply3733925949)
## 思路
# 思路
本题这是回溯法的经典题目。
@@ -37,7 +37,7 @@
直接的解法当然是使用for循环例如示例中k为2很容易想到 用两个for循环这样就可以输出 和示例中一样的结果。
代码如下:
```
```CPP
int n = 4;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
@@ -49,7 +49,7 @@ for (int i = 1; i <= n; i++) {
输入n = 100, k = 3
那么就三层for循环代码如下
```
```CPP
int n = 100;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
@@ -301,7 +301,7 @@ for (int i = startIndex; i <= n - (k - path.size()) + 1; i++) // i为本次搜
优化后整体代码如下:
```
```CPP
class Solution {
private:
vector<vector<int>> result;
@@ -336,10 +336,10 @@ public:
## 其他语言版本
# 其他语言版本
Java
## Java
```java
class Solution {
List<List<Integer>> result = new ArrayList<>();
@@ -397,7 +397,25 @@ class Solution(object):
return result
```
Python
## Python
```python
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
res = []
path = []
def backtrack(n, k, StartIndex):
if len(path) == k:
res.append(path[:])
return
for i in range(StartIndex, n-(k-len(path)) + 2):
path.append(i)
backtrack(n, k, i+1)
path.pop()
backtrack(n, k, 1)
return res
```
剪枝
```python3
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
@@ -406,15 +424,19 @@ class Solution:
def backtrack(n,k,startIndex):
if len(path) == k:
res.append(path[:])
return
for i in range(startIndex,n+1):
return
for i in range(startIndex,n-(k-len(path))+2): #优化的地方
path.append(i) #处理节点
backtrack(n,k,i+1) #递归
path.pop() #回溯,撤销处理的节点
backtrack(n,k,1)
return res
backtrack(n,k,1)
return res
```
javascript
## javascript
剪枝:
```javascript
let result = []
let path = []
@@ -434,8 +456,11 @@ const combineHelper = (n, k, startIndex) => {
path.pop()
}
}
```
Go
```
## Go
```Go
var res [][]int
func combine(n int, k int) [][]int {
@@ -462,8 +487,35 @@ func backtrack(n,k,start int,track []int){
}
}
```
剪枝:
```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]
}
}
```
C:
## C
```c
int* path;
int pathTop;
@@ -517,6 +569,60 @@ int** combine(int n, int k, int* returnSize, int** returnColumnSizes){
}
```
剪枝:
```c
int* path;
int pathTop;
int** ans;
int ansTop;
void backtracking(int n, int k,int startIndex) {
//当path中元素个数为k个时我们需要将path数组放入ans二维数组中
if(pathTop == k) {
//path数组为我们动态申请若直接将其地址放入二维数组path数组中的值会随着我们回溯而逐渐变化
//因此创建新的数组存储path中的值
int* temp = (int*)malloc(sizeof(int) * k);
int i;
for(i = 0; i < k; i++) {
temp[i] = path[i];
}
ans[ansTop++] = temp;
return ;
}
int j;
for(j = startIndex; j <= n- (k - pathTop) + 1;j++) {
//将当前结点放入path数组
path[pathTop++] = j;
//进行递归
backtracking(n, k, j + 1);
//进行回溯,将数组最上层结点弹出
pathTop--;
}
}
int** combine(int n, int k, int* returnSize, int** returnColumnSizes){
//path数组存储符合条件的结果
path = (int*)malloc(sizeof(int) * k);
//ans二维数组存储符合条件的结果数组的集合。数组足够大避免极端情况
ans = (int**)malloc(sizeof(int*) * 10000);
pathTop = ansTop = 0;
//回溯算法
backtracking(n, k, 1);
//最后的返回大小为ans数组大小
*returnSize = ansTop;
//returnColumnSizes数组存储ans二维数组对应下标中一维数组的长度都为k
*returnColumnSizes = (int*)malloc(sizeof(int) *(*returnSize));
int i;
for(i = 0; i < *returnSize; i++) {
(*returnColumnSizes)[i] = k;
}
//返回ans二维数组
return ans;
}
```
-----------------------
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
* B站视频[代码随想录](https://space.bilibili.com/525438321)