mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-09 11:34:46 +08:00
@ -21,12 +21,12 @@
|
||||
|
||||
说明:尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[还得用回溯算法!| LeetCode:17.电话号码的字母组合](https://www.bilibili.com/video/BV1yV4y1V7Ug),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html)::[还得用回溯算法!| LeetCode:17.电话号码的字母组合](https://www.bilibili.com/video/BV1yV4y1V7Ug),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
|
||||
# 思路
|
||||
## 思路
|
||||
|
||||
从示例上来说,输入"23",最直接的想法就是两层for循环遍历了吧,正好把组合的情况都输出了。
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
2. 两个字母就两个for循环,三个字符我就三个for循环,以此类推,然后发现代码根本写不出来
|
||||
3. 输入1 * #按键等等异常情况
|
||||
|
||||
## 数字和字母如何映射
|
||||
### 数字和字母如何映射
|
||||
|
||||
可以使用map或者定义一个二维数组,例如:string letterMap[10],来做映射,我这里定义一个二维数组,代码如下:
|
||||
|
||||
@ -59,7 +59,7 @@ const string letterMap[10] = {
|
||||
};
|
||||
```
|
||||
|
||||
## 回溯法来解决n个for循环的问题
|
||||
### 回溯法来解决n个for循环的问题
|
||||
|
||||
对于回溯法还不了解的同学看这篇:[关于回溯算法,你该了解这些!](https://programmercarl.com/回溯算法理论基础.html)
|
||||
|
||||
@ -134,9 +134,6 @@ for (int i = 0; i < letters.size(); i++) {
|
||||
|
||||
**但是要知道会有这些异常,如果是现场面试中,一定要考虑到!**
|
||||
|
||||
|
||||
## C++代码
|
||||
|
||||
关键地方都讲完了,按照[关于回溯算法,你该了解这些!](https://programmercarl.com/回溯算法理论基础.html)中的回溯法模板,不难写出如下C++代码:
|
||||
|
||||
|
||||
@ -233,7 +230,7 @@ public:
|
||||
|
||||
所以大家可以按照版本一来写就可以了。
|
||||
|
||||
# 总结
|
||||
## 总结
|
||||
|
||||
本篇将题目的三个要点一一列出,并重点强调了和前面讲解过的[77. 组合](https://programmercarl.com/0077.组合.html)和[216.组合总和III](https://programmercarl.com/0216.组合总和III.html)的区别,本题是多个集合求组合,所以在回溯的搜索过程中,都有一些细节需要注意的。
|
||||
|
||||
@ -241,10 +238,10 @@ public:
|
||||
|
||||
|
||||
|
||||
# 其他语言版本
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
## Java
|
||||
### Java
|
||||
```Java
|
||||
class Solution {
|
||||
|
||||
@ -286,7 +283,7 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
## Python
|
||||
### Python
|
||||
回溯
|
||||
```python
|
||||
class Solution:
|
||||
@ -435,7 +432,7 @@ class Solution:
|
||||
|
||||
|
||||
|
||||
## Go
|
||||
### Go
|
||||
|
||||
主要在于递归中传递下一个数字
|
||||
|
||||
@ -470,7 +467,7 @@ func dfs(digits string, start int) {
|
||||
}
|
||||
```
|
||||
|
||||
## javaScript
|
||||
### JavaScript
|
||||
|
||||
```js
|
||||
var letterCombinations = function(digits) {
|
||||
@ -497,7 +494,7 @@ var letterCombinations = function(digits) {
|
||||
};
|
||||
```
|
||||
|
||||
## TypeScript
|
||||
### TypeScript
|
||||
|
||||
```typescript
|
||||
function letterCombinations(digits: string): string[] {
|
||||
@ -531,7 +528,7 @@ function letterCombinations(digits: string): string[] {
|
||||
};
|
||||
```
|
||||
|
||||
## Rust
|
||||
### Rust
|
||||
|
||||
```Rust
|
||||
const map: [&str; 10] = [
|
||||
@ -563,7 +560,7 @@ impl Solution {
|
||||
}
|
||||
```
|
||||
|
||||
## C
|
||||
### C
|
||||
|
||||
```c
|
||||
char* path;
|
||||
@ -625,7 +622,7 @@ char ** letterCombinations(char * digits, int* returnSize){
|
||||
}
|
||||
```
|
||||
|
||||
## Swift
|
||||
### Swift
|
||||
|
||||
```swift
|
||||
func letterCombinations(_ digits: String) -> [String] {
|
||||
@ -666,7 +663,7 @@ func letterCombinations(_ digits: String) -> [String] {
|
||||
}
|
||||
```
|
||||
|
||||
## Scala:
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
@ -702,3 +699,4 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -6,8 +6,7 @@
|
||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
如果对回溯法理论还不清楚的同学,可以先看这个视频[视频来了!!带你学透回溯算法(理论篇)](https://mp.weixin.qq.com/s/wDd5azGIYWjbU0fdua_qBg)
|
||||
> 如果对回溯法理论还不清楚的同学,可以先看这个视频[视频来了!!带你学透回溯算法(理论篇)](https://mp.weixin.qq.com/s/wDd5azGIYWjbU0fdua_qBg)
|
||||
|
||||
# 37. 解数独
|
||||
|
||||
@ -35,11 +34,9 @@
|
||||
* 你可以假设给定的数独只有唯一解。
|
||||
* 给定数独永远是 9x9 形式的。
|
||||
|
||||
# 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[回溯算法二维递归?解数独不过如此!| LeetCode:37. 解数独](https://www.bilibili.com/video/BV1TW4y1471V/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
## 算法公开课
|
||||
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[回溯算法二维递归?解数独不过如此!| LeetCode:37. 解数独](https://www.bilibili.com/video/BV1TW4y1471V/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
## 思路
|
||||
|
||||
@ -764,3 +761,4 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -39,11 +39,11 @@ candidates 中的数字可以无限制重复被选取。
|
||||
[3,5]
|
||||
]
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[Leetcode:39. 组合总和讲解](https://www.bilibili.com/video/BV1KT4y1M7HJ),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[Leetcode:39. 组合总和讲解](https://www.bilibili.com/video/BV1KT4y1M7HJ),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
# 思路
|
||||
## 思路
|
||||
|
||||
|
||||
题目中的**无限制重复被选取,吓得我赶紧想想 出现0 可咋办**,然后看到下面提示:1 <= candidates[i] <= 200,我就放心了。
|
||||
@ -57,7 +57,7 @@ candidates 中的数字可以无限制重复被选取。
|
||||
|
||||
而在[77.组合](https://programmercarl.com/0077.组合.html)和[216.组合总和III](https://programmercarl.com/0216.组合总和III.html) 中都可以知道要递归K层,因为要取k个元素的组合。
|
||||
|
||||
## 回溯三部曲
|
||||
### 回溯三部曲
|
||||
|
||||
* 递归函数参数
|
||||
|
||||
@ -156,7 +156,7 @@ public:
|
||||
};
|
||||
```
|
||||
|
||||
## 剪枝优化
|
||||
### 剪枝优化
|
||||
|
||||
在这个树形结构中:
|
||||
|
||||
@ -217,7 +217,7 @@ public:
|
||||
* 时间复杂度: O(n * 2^n),注意这只是复杂度的上界,因为剪枝的存在,真实的时间复杂度远小于此
|
||||
* 空间复杂度: O(target)
|
||||
|
||||
# 总结
|
||||
## 总结
|
||||
|
||||
本题和我们之前讲过的[77.组合](https://programmercarl.com/0077.组合.html)、[216.组合总和III](https://programmercarl.com/0216.组合总和III.html)有两点不同:
|
||||
|
||||
@ -238,10 +238,10 @@ public:
|
||||
|
||||
|
||||
|
||||
# 其他语言版本
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
## Java
|
||||
### Java
|
||||
|
||||
```Java
|
||||
// 剪枝优化
|
||||
@ -271,7 +271,7 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
## Python
|
||||
### Python
|
||||
|
||||
回溯(版本一)
|
||||
|
||||
@ -370,7 +370,7 @@ class Solution:
|
||||
|
||||
```
|
||||
|
||||
## Go
|
||||
### Go
|
||||
|
||||
主要在于递归中传递下一个数字
|
||||
|
||||
@ -404,7 +404,7 @@ func dfs(candidates []int, start int, target int) {
|
||||
}
|
||||
```
|
||||
|
||||
## JavaScript
|
||||
### JavaScript
|
||||
|
||||
```js
|
||||
var combinationSum = function(candidates, target) {
|
||||
@ -430,7 +430,7 @@ var combinationSum = function(candidates, target) {
|
||||
};
|
||||
```
|
||||
|
||||
## TypeScript
|
||||
### TypeScript
|
||||
|
||||
```typescript
|
||||
function combinationSum(candidates: number[], target: number): number[][] {
|
||||
@ -456,7 +456,7 @@ function combinationSum(candidates: number[], target: number): number[][] {
|
||||
};
|
||||
```
|
||||
|
||||
## Rust
|
||||
### Rust
|
||||
|
||||
```Rust
|
||||
impl Solution {
|
||||
@ -485,7 +485,7 @@ impl Solution {
|
||||
}
|
||||
```
|
||||
|
||||
## C
|
||||
### C
|
||||
|
||||
```c
|
||||
int* path;
|
||||
@ -541,7 +541,7 @@ int** combinationSum(int* candidates, int candidatesSize, int target, int* retur
|
||||
}
|
||||
```
|
||||
|
||||
## Swift
|
||||
### Swift
|
||||
|
||||
```swift
|
||||
func combinationSum(_ candidates: [Int], _ target: Int) -> [[Int]] {
|
||||
@ -570,7 +570,7 @@ func combinationSum(_ candidates: [Int], _ target: Int) -> [[Int]] {
|
||||
}
|
||||
```
|
||||
|
||||
## Scala
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
@ -604,3 +604,4 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -41,13 +41,11 @@ candidates 中的每个数字在每个组合中只能使用一次。
|
||||
]
|
||||
```
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[回溯算法中的去重,树层去重树枝去重,你弄清楚了没?| LeetCode:40.组合总和II](https://www.bilibili.com/video/BV12V4y1V73A),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[回溯算法中的去重,树层去重树枝去重,你弄清楚了没?| LeetCode:40.组合总和II](https://www.bilibili.com/video/BV12V4y1V73A),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
|
||||
|
||||
# 思路
|
||||
## 思路
|
||||
|
||||
|
||||
这道题目和[39.组合总和](https://programmercarl.com/0039.组合总和.html)如下区别:
|
||||
@ -86,7 +84,7 @@ candidates 中的每个数字在每个组合中只能使用一次。
|
||||
|
||||
可以看到图中,每个节点相对于 [39.组合总和](https://mp.weixin.qq.com/s/FLg8G6EjVcxBjwCbzpACPw)我多加了used数组,这个used数组下面会重点介绍。
|
||||
|
||||
## 回溯三部曲
|
||||
### 回溯三部曲
|
||||
|
||||
* **递归函数参数**
|
||||
|
||||
@ -217,7 +215,7 @@ public:
|
||||
* 时间复杂度: O(n * 2^n)
|
||||
* 空间复杂度: O(n)
|
||||
|
||||
## 补充
|
||||
### 补充
|
||||
|
||||
这里直接用startIndex来去重也是可以的, 就不用used数组了。
|
||||
|
||||
@ -257,7 +255,7 @@ public:
|
||||
|
||||
```
|
||||
|
||||
# 总结
|
||||
## 总结
|
||||
|
||||
本题同样是求组合总和,但就是因为其数组candidates有重复元素,而要求不能有重复的组合,所以相对于[39.组合总和](https://programmercarl.com/0039.组合总和.html)难度提升了不少。
|
||||
|
||||
@ -265,14 +263,10 @@ public:
|
||||
|
||||
所以Carl有必要把去重的这块彻彻底底的给大家讲清楚,**就连“树层去重”和“树枝去重”都是我自创的词汇,希望对大家理解有帮助!**
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
|
||||
|
||||
# 其他语言版本
|
||||
|
||||
|
||||
## Java
|
||||
### Java
|
||||
**使用标记数组**
|
||||
```Java
|
||||
class Solution {
|
||||
@ -355,7 +349,7 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
## Python
|
||||
### Python
|
||||
回溯
|
||||
```python
|
||||
class Solution:
|
||||
@ -442,7 +436,7 @@ class Solution:
|
||||
self.combinationSumHelper(candidates, target - candidates[i], i + 1, path, results)
|
||||
path.pop()
|
||||
```
|
||||
## Go
|
||||
### Go
|
||||
主要在于如何在回溯中去重
|
||||
|
||||
**使用used数组**
|
||||
@ -518,7 +512,7 @@ func dfs(candidates []int, start int, target int) {
|
||||
}
|
||||
}
|
||||
```
|
||||
## javaScript
|
||||
### JavaScript
|
||||
|
||||
```js
|
||||
/**
|
||||
@ -588,7 +582,7 @@ var combinationSum2 = function(candidates, target) {
|
||||
};
|
||||
```
|
||||
|
||||
## TypeScript
|
||||
### TypeScript
|
||||
|
||||
```typescript
|
||||
function combinationSum2(candidates: number[], target: number): number[][] {
|
||||
@ -619,7 +613,7 @@ function combinationSum2(candidates: number[], target: number): number[][] {
|
||||
};
|
||||
```
|
||||
|
||||
## Rust
|
||||
### Rust
|
||||
|
||||
```Rust
|
||||
impl Solution {
|
||||
@ -654,7 +648,7 @@ impl Solution {
|
||||
}
|
||||
```
|
||||
|
||||
## C
|
||||
### C
|
||||
|
||||
```c
|
||||
int* path;
|
||||
@ -716,7 +710,7 @@ int** combinationSum2(int* candidates, int candidatesSize, int target, int* retu
|
||||
}
|
||||
```
|
||||
|
||||
## Swift
|
||||
### Swift
|
||||
|
||||
```swift
|
||||
func combinationSum2(_ candidates: [Int], _ target: Int) -> [[Int]] {
|
||||
@ -749,7 +743,7 @@ func combinationSum2(_ candidates: [Int], _ target: Int) -> [[Int]] {
|
||||
```
|
||||
|
||||
|
||||
## Scala
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
@ -784,3 +778,4 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -24,9 +24,9 @@
|
||||
]
|
||||
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[组合与排列的区别,回溯算法求解的时候,有何不同?| LeetCode:46.全排列](https://www.bilibili.com/video/BV19v4y1S79W/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[组合与排列的区别,回溯算法求解的时候,有何不同?| LeetCode:46.全排列](https://www.bilibili.com/video/BV19v4y1S79W/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
|
||||
## 思路
|
||||
@ -491,3 +491,4 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -31,9 +31,9 @@
|
||||
* 1 <= nums.length <= 8
|
||||
* -10 <= nums[i] <= 10
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[回溯算法求解全排列,如何去重?| LeetCode:47.全排列 II](https://www.bilibili.com/video/BV1R84y1i7Tm/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[回溯算法求解全排列,如何去重?| LeetCode:47.全排列 II](https://www.bilibili.com/video/BV1R84y1i7Tm/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
|
||||
## 思路
|
||||
@ -58,7 +58,7 @@
|
||||
|
||||
在[46.全排列](https://programmercarl.com/0046.全排列.html)中已经详细讲解了排列问题的写法,在[40.组合总和II](https://programmercarl.com/0040.组合总和II.html) 、[90.子集II](https://programmercarl.com/0090.子集II.html)中详细讲解了去重的写法,所以这次我就不用回溯三部曲分析了,直接给出代码,如下:
|
||||
|
||||
## C++代码
|
||||
|
||||
|
||||
```CPP
|
||||
class Solution {
|
||||
@ -170,7 +170,7 @@ if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == true) {
|
||||
if (i > 0 && nums[i] == nums[i - 1]) {
|
||||
continue;
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
其实并不行,一定要加上 `used[i - 1] == false`或者`used[i - 1] == true`,因为 used[i - 1] 要一直是 true 或者一直是false 才可以,而不是 一会是true 一会又是false。 所以这个条件要写上。
|
||||
|
||||
@ -179,7 +179,7 @@ if (i > 0 && nums[i] == nums[i - 1]) {
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
### java
|
||||
### Java
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
@ -221,7 +221,7 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
### python
|
||||
Python
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
@ -526,3 +526,4 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -28,9 +28,9 @@ n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,
|
||||
* 输入:n = 1
|
||||
* 输出:[["Q"]]
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[这就是传说中的N皇后? 回溯算法安排!| LeetCode:51.N皇后](https://www.bilibili.com/video/BV1Rd4y1c7Bq/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[这就是传说中的N皇后? 回溯算法安排!| LeetCode:51.N皇后](https://www.bilibili.com/video/BV1Rd4y1c7Bq/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
|
||||
## 思路
|
||||
@ -864,3 +864,4 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -43,13 +43,11 @@ n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并
|
||||
".Q.."]
|
||||
]
|
||||
|
||||
# 思路
|
||||
## 思路
|
||||
|
||||
|
||||
详看:[51.N皇后](https://mp.weixin.qq.com/s/lU_QwCMj6g60nh8m98GAWg) ,基本没有区别
|
||||
|
||||
# C++代码
|
||||
|
||||
```CPP
|
||||
class Solution {
|
||||
private:
|
||||
@ -100,8 +98,9 @@ public:
|
||||
};
|
||||
```
|
||||
|
||||
# 其他语言补充
|
||||
JavaScript
|
||||
## 其他语言补充
|
||||
### JavaScript
|
||||
|
||||
```javascript
|
||||
var totalNQueens = function(n) {
|
||||
let count = 0;
|
||||
@ -146,7 +145,7 @@ var totalNQueens = function(n) {
|
||||
};
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
### TypeScript
|
||||
|
||||
```typescript
|
||||
// 0-该格为空,1-该格有皇后
|
||||
@ -199,7 +198,7 @@ function checkValid(chess: GridStatus[][], i: number, j: number, n: number): boo
|
||||
}
|
||||
```
|
||||
|
||||
C
|
||||
### C
|
||||
|
||||
```c
|
||||
//path[i]为在i行,path[i]列上存在皇后
|
||||
@ -258,7 +257,8 @@ int totalNQueens(int n){
|
||||
return answer;
|
||||
}
|
||||
```
|
||||
Java
|
||||
### Java
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
int count = 0;
|
||||
@ -310,4 +310,3 @@ class Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -5,10 +5,6 @@
|
||||
</a>
|
||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 第77题. 组合
|
||||
|
||||
[力扣题目链接](https://leetcode.cn/problems/combinations/ )
|
||||
@ -27,13 +23,12 @@
|
||||
[1,4],
|
||||
]
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[带你学透回溯算法-组合问题(对应力扣题目:77.组合)](https://www.bilibili.com/video/BV1ti4y1L7cv),[组合问题的剪枝操作](https://www.bilibili.com/video/BV1wi4y157er),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
|
||||
**《代码随想录》算法视频公开课:[带你学透回溯算法-组合问题(对应力扣题目:77.组合)](https://www.bilibili.com/video/BV1ti4y1L7cv),[组合问题的剪枝操作](https://www.bilibili.com/video/BV1wi4y157er),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
|
||||
# 思路
|
||||
## 思路
|
||||
|
||||
|
||||
本题是回溯法的经典题目。
|
||||
@ -108,7 +103,7 @@ for (int i = 1; i <= n; i++) {
|
||||
在[关于回溯算法,你该了解这些!](https://programmercarl.com/回溯算法理论基础.html)中我们提到了回溯法三部曲,那么我们按照回溯法三部曲开始正式讲解代码了。
|
||||
|
||||
|
||||
## 回溯法三部曲
|
||||
### 回溯法三部曲
|
||||
|
||||
* 递归函数的返回值以及参数
|
||||
|
||||
@ -345,12 +340,10 @@ public:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
### Java:
|
||||
### Java
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
@ -451,7 +444,7 @@ func dfs(n int, k int, start int) {
|
||||
}
|
||||
```
|
||||
|
||||
### javascript
|
||||
### Javascript
|
||||
|
||||
剪枝:
|
||||
|
||||
@ -751,3 +744,4 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -7,8 +7,11 @@
|
||||
|
||||
|
||||
# 77.组合优化
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[组合问题的剪枝操作](https://www.bilibili.com/video/BV1wi4y157er),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[组合问题的剪枝操作](https://www.bilibili.com/video/BV1wi4y157er),相信结合视频在看本篇题解,更有助于大家对本题的理解。**
|
||||
|
||||
## 思路
|
||||
|
||||
在[回溯算法:求组合问题!](https://programmercarl.com/0077.组合.html)中,我们通过回溯搜索法,解决了n个数中求k个数的组合问题。
|
||||
|
||||
@ -46,7 +49,7 @@ public:
|
||||
};
|
||||
```
|
||||
|
||||
# 剪枝优化
|
||||
## 剪枝优化
|
||||
|
||||
我们说过,回溯法虽然是暴力搜索,但也有时候可以有点剪枝优化一下的。
|
||||
|
||||
@ -135,7 +138,7 @@ public:
|
||||
|
||||
|
||||
|
||||
# 总结
|
||||
## 总结
|
||||
|
||||
本篇我们针对求组合问题的回溯法代码做了剪枝优化,这个优化如果不画图的话,其实不好理解,也不好讲清楚。
|
||||
|
||||
@ -143,14 +146,10 @@ public:
|
||||
|
||||
**就酱,学到了就帮Carl转发一下吧,让更多的同学知道这里!**
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
### Java
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
List<List<Integer>> result = new ArrayList<>();
|
||||
@ -179,7 +178,8 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
### Python
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def combine(self, n: int, k: int) -> List[List[int]]:
|
||||
@ -199,7 +199,8 @@ class Solution:
|
||||
|
||||
|
||||
```
|
||||
Go:
|
||||
### Go
|
||||
|
||||
```Go
|
||||
var (
|
||||
path []int
|
||||
@ -227,7 +228,7 @@ func dfs(n int, k int, start int) {
|
||||
}
|
||||
```
|
||||
|
||||
javaScript:
|
||||
### JavaScript
|
||||
|
||||
```js
|
||||
var combine = function(n, k) {
|
||||
@ -249,7 +250,7 @@ var combine = function(n, k) {
|
||||
};
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
### TypeScript
|
||||
|
||||
```typescript
|
||||
function combine(n: number, k: number): number[][] {
|
||||
@ -270,7 +271,7 @@ function combine(n: number, k: number): number[][] {
|
||||
};
|
||||
```
|
||||
|
||||
Rust:
|
||||
### Rust
|
||||
|
||||
```Rust
|
||||
impl Solution {
|
||||
@ -296,7 +297,7 @@ impl Solution {
|
||||
}
|
||||
```
|
||||
|
||||
C:
|
||||
### C
|
||||
|
||||
```c
|
||||
int* path;
|
||||
@ -351,7 +352,7 @@ int** combine(int n, int k, int* returnSize, int** returnColumnSizes){
|
||||
}
|
||||
```
|
||||
|
||||
Swift:
|
||||
### Swift
|
||||
|
||||
```swift
|
||||
func combine(_ n: Int, _ k: Int) -> [[Int]] {
|
||||
@ -381,7 +382,7 @@ func combine(_ n: Int, _ k: Int) -> [[Int]] {
|
||||
}
|
||||
```
|
||||
|
||||
Scala:
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
@ -414,3 +415,4 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -27,12 +27,12 @@
|
||||
[]
|
||||
]
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[回溯算法解决子集问题,树上节点都是目标集和! | LeetCode:78.子集](https://www.bilibili.com/video/BV1U84y1q7Ci),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[回溯算法解决子集问题,树上节点都是目标集和! | LeetCode:78.子集](https://www.bilibili.com/video/BV1U84y1q7Ci),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
|
||||
# 思路
|
||||
## 思路
|
||||
|
||||
求子集问题和[77.组合](https://programmercarl.com/0077.组合.html)和[131.分割回文串](https://programmercarl.com/0131.分割回文串.html)又不一样了。
|
||||
|
||||
@ -52,7 +52,7 @@
|
||||
|
||||
从图中红线部分,可以看出**遍历这个树的时候,把所有节点都记录下来,就是要求的子集集合**。
|
||||
|
||||
## 回溯三部曲
|
||||
### 回溯三部曲
|
||||
|
||||
* 递归函数参数
|
||||
|
||||
@ -102,8 +102,6 @@ for (int i = startIndex; i < nums.size(); i++) {
|
||||
}
|
||||
```
|
||||
|
||||
## C++代码
|
||||
|
||||
根据[关于回溯算法,你该了解这些!](https://programmercarl.com/回溯算法理论基础.html)给出的回溯算法模板:
|
||||
|
||||
```
|
||||
@ -158,7 +156,7 @@ public:
|
||||
|
||||
并不会,因为每次递归的下一层就是从i+1开始的。
|
||||
|
||||
# 总结
|
||||
## 总结
|
||||
|
||||
相信大家经过了
|
||||
* 组合问题:
|
||||
@ -178,10 +176,10 @@ public:
|
||||
|
||||
**而组合问题、分割问题是收集树形结构中叶子节点的结果**。
|
||||
|
||||
# 其他语言版本
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
## Java
|
||||
### Java
|
||||
```java
|
||||
class Solution {
|
||||
List<List<Integer>> result = new ArrayList<>();// 存放符合条件结果的集合
|
||||
@ -205,7 +203,7 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
## Python
|
||||
### Python
|
||||
```python
|
||||
class Solution:
|
||||
def subsets(self, nums):
|
||||
@ -224,7 +222,7 @@ class Solution:
|
||||
path.pop()
|
||||
```
|
||||
|
||||
## Go
|
||||
### Go
|
||||
```Go
|
||||
var (
|
||||
path []int
|
||||
@ -248,7 +246,7 @@ func dfs(nums []int, start int) {
|
||||
}
|
||||
```
|
||||
|
||||
## Javascript
|
||||
### Javascript
|
||||
|
||||
```Javascript
|
||||
var subsets = function(nums) {
|
||||
@ -267,7 +265,7 @@ var subsets = function(nums) {
|
||||
};
|
||||
```
|
||||
|
||||
## TypeScript
|
||||
### TypeScript
|
||||
|
||||
```typescript
|
||||
function subsets(nums: number[]): number[][] {
|
||||
@ -287,7 +285,7 @@ function subsets(nums: number[]): number[][] {
|
||||
};
|
||||
```
|
||||
|
||||
## Rust
|
||||
### Rust
|
||||
|
||||
```Rust
|
||||
impl Solution {
|
||||
@ -311,7 +309,7 @@ impl Solution {
|
||||
}
|
||||
```
|
||||
|
||||
## C
|
||||
### C
|
||||
|
||||
```c
|
||||
int* path;
|
||||
@ -369,7 +367,7 @@ int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes)
|
||||
}
|
||||
```
|
||||
|
||||
## Swift
|
||||
### Swift
|
||||
|
||||
```swift
|
||||
func subsets(_ nums: [Int]) -> [[Int]] {
|
||||
@ -392,7 +390,7 @@ func subsets(_ nums: [Int]) -> [[Int]] {
|
||||
}
|
||||
```
|
||||
|
||||
## Scala
|
||||
### Scala
|
||||
|
||||
思路一: 使用本题解思路
|
||||
|
||||
@ -451,3 +449,4 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -3,8 +3,6 @@
|
||||
<img src="../pics/训练营.png" width="1000"/>
|
||||
</a>
|
||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
# 90.子集II
|
||||
|
||||
[力扣题目链接](https://leetcode.cn/problems/subsets-ii/)
|
||||
@ -25,9 +23,9 @@
|
||||
[]
|
||||
]
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[回溯算法解决子集问题,如何去重?| LeetCode:90.子集II](https://www.bilibili.com/video/BV1vm4y1F71J/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[回溯算法解决子集问题,如何去重?| LeetCode:90.子集II](https://www.bilibili.com/video/BV1vm4y1F71J/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
|
||||
## 思路
|
||||
@ -240,7 +238,7 @@ class Solution {
|
||||
|
||||
|
||||
|
||||
#### Python3
|
||||
### Python3
|
||||
|
||||
回溯 利用used数组去重
|
||||
```python
|
||||
@ -646,3 +644,4 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -40,16 +40,12 @@
|
||||
* 0 <= s.length <= 3000
|
||||
* s 仅由数字组成
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[93.复原IP地址](https://www.bilibili.com/video/BV1XP4y1U73i/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
# 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[回溯算法如何分割字符串并判断是合法IP?| LeetCode:93.复原IP地址](https://www.bilibili.com/video/BV1XP4y1U73i/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[回溯算法如何分割字符串并判断是合法IP?| LeetCode:93.复原IP地址](https://www.bilibili.com/video/BV1XP4y1U73i/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
|
||||
# 思路
|
||||
## 思路
|
||||
|
||||
做这道题目之前,最好先把[131.分割回文串](https://programmercarl.com/0131.分割回文串.html)这个做了。
|
||||
|
||||
@ -63,7 +59,7 @@
|
||||

|
||||
|
||||
|
||||
## 回溯三部曲
|
||||
### 回溯三部曲
|
||||
|
||||
* 递归参数
|
||||
|
||||
@ -134,7 +130,7 @@ for (int i = startIndex; i < s.size(); i++) {
|
||||
}
|
||||
```
|
||||
|
||||
## 判断子串是否合法
|
||||
### 判断子串是否合法
|
||||
|
||||
最后就是在写一个判断段位是否是有效段位了。
|
||||
|
||||
@ -169,8 +165,6 @@ bool isValid(const string& s, int start, int end) {
|
||||
}
|
||||
```
|
||||
|
||||
## C++代码
|
||||
|
||||
|
||||
根据[关于回溯算法,你该了解这些!](https://programmercarl.com/回溯算法理论基础.html)给出的回溯算法模板:
|
||||
|
||||
@ -247,7 +241,7 @@ public:
|
||||
* 时间复杂度: O(3^4),IP地址最多包含4个数字,每个数字最多有3种可能的分割方式,则搜索树的最大深度为4,每个节点最多有3个子节点。
|
||||
* 空间复杂度: O(n)
|
||||
|
||||
# 总结
|
||||
## 总结
|
||||
|
||||
在[131.分割回文串](https://programmercarl.com/0131.分割回文串.html)中我列举的分割字符串的难点,本题都覆盖了。
|
||||
|
||||
@ -259,9 +253,9 @@ public:
|
||||
|
||||
|
||||
|
||||
# 其他语言版本
|
||||
## 其他语言版本
|
||||
|
||||
## java
|
||||
### Java
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
@ -402,7 +396,7 @@ class Solution {
|
||||
```
|
||||
|
||||
|
||||
## python
|
||||
### Python
|
||||
|
||||
回溯(版本一)
|
||||
```python
|
||||
@ -478,9 +472,7 @@ class Solution:
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Go
|
||||
### Go
|
||||
|
||||
```go
|
||||
var (
|
||||
@ -517,7 +509,7 @@ func dfs(s string, start int) {
|
||||
}
|
||||
```
|
||||
|
||||
## JavaScript
|
||||
### JavaScript
|
||||
|
||||
```js
|
||||
/**
|
||||
@ -547,7 +539,7 @@ var restoreIpAddresses = function(s) {
|
||||
};
|
||||
```
|
||||
|
||||
## TypeScript
|
||||
### TypeScript
|
||||
|
||||
```typescript
|
||||
function isValidIpSegment(str: string): boolean {
|
||||
@ -586,7 +578,7 @@ function restoreIpAddresses(s: string): string[] {
|
||||
};
|
||||
```
|
||||
|
||||
## Rust
|
||||
### Rust
|
||||
|
||||
```Rust
|
||||
impl Solution {
|
||||
@ -643,7 +635,7 @@ impl Solution {
|
||||
}
|
||||
```
|
||||
|
||||
## C
|
||||
### C
|
||||
```c
|
||||
//记录结果
|
||||
char** result;
|
||||
@ -719,7 +711,7 @@ char ** restoreIpAddresses(char * s, int* returnSize){
|
||||
}
|
||||
```
|
||||
|
||||
## Swift
|
||||
### Swift
|
||||
|
||||
```swift
|
||||
// 判断区间段是否合法
|
||||
@ -766,7 +758,7 @@ func restoreIpAddresses(_ s: String) -> [String] {
|
||||
}
|
||||
```
|
||||
|
||||
## Scala
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
@ -813,3 +805,4 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -23,12 +23,12 @@
|
||||
["a","a","b"]
|
||||
]
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[131.分割回文串](https://www.bilibili.com/video/BV1c54y1e7k6),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[131.分割回文串](https://www.bilibili.com/video/BV1c54y1e7k6),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
|
||||
# 思路
|
||||
## 思路
|
||||
|
||||
本题这涉及到两个关键问题:
|
||||
|
||||
@ -58,7 +58,7 @@
|
||||
|
||||
此时可以发现,切割问题的回溯搜索的过程和组合问题的回溯搜索的过程是差不多的。
|
||||
|
||||
## 回溯三部曲
|
||||
### 回溯三部曲
|
||||
|
||||
* 递归函数参数
|
||||
|
||||
@ -124,7 +124,7 @@ for (int i = startIndex; i < s.size(); i++) {
|
||||
|
||||
**注意切割过的位置,不能重复切割,所以,backtracking(s, i + 1); 传入下一层的起始位置为i + 1**。
|
||||
|
||||
## 判断回文子串
|
||||
### 判断回文子串
|
||||
|
||||
最后我们看一下回文子串要如何判断了,判断一个字符串是否是回文。
|
||||
|
||||
@ -147,8 +147,6 @@ for (int i = startIndex; i < s.size(); i++) {
|
||||
|
||||
此时关键代码已经讲解完毕,整体代码如下(详细注释了)
|
||||
|
||||
## C++整体代码
|
||||
|
||||
根据Carl给出的回溯算法模板:
|
||||
|
||||
```CPP
|
||||
@ -212,7 +210,7 @@ public:
|
||||
* 时间复杂度: O(n * 2^n)
|
||||
* 空间复杂度: O(n^2)
|
||||
|
||||
# 优化
|
||||
## 优化
|
||||
|
||||
上面的代码还存在一定的优化空间, 在于如何更高效的计算一个子字符串是否是回文字串。上述代码```isPalindrome```函数运用双指针的方法来判定对于一个字符串```s```, 给定起始下标和终止下标, 截取出的子字符串是否是回文字串。但是其中有一定的重复计算存在:
|
||||
|
||||
@ -272,7 +270,7 @@ public:
|
||||
|
||||
```
|
||||
|
||||
# 总结
|
||||
## 总结
|
||||
|
||||
这道题目在leetcode上是中等,但可以说是hard的题目了,但是代码其实就是按照模板的样子来的。
|
||||
|
||||
@ -306,10 +304,10 @@ public:
|
||||
|
||||
|
||||
|
||||
# 其他语言版本
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
## Java
|
||||
### Java
|
||||
```Java
|
||||
class Solution {
|
||||
List<List<String>> lists = new ArrayList<>();
|
||||
@ -351,7 +349,7 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
## Python
|
||||
### Python
|
||||
回溯 基本版
|
||||
```python
|
||||
class Solution:
|
||||
@ -473,7 +471,7 @@ class Solution:
|
||||
return all(s[i] == s[len(s) - 1 - i] for i in range(len(s) // 2))
|
||||
|
||||
```
|
||||
## Go
|
||||
### Go
|
||||
```go
|
||||
var (
|
||||
path []string // 放已经回文的子串
|
||||
@ -512,7 +510,7 @@ func isPalindrome(s string) bool {
|
||||
}
|
||||
```
|
||||
|
||||
## javaScript
|
||||
### JavaScript
|
||||
|
||||
```js
|
||||
/**
|
||||
@ -545,7 +543,7 @@ var partition = function(s) {
|
||||
};
|
||||
```
|
||||
|
||||
## TypeScript
|
||||
### TypeScript
|
||||
|
||||
```typescript
|
||||
function partition(s: string): string[][] {
|
||||
@ -582,7 +580,7 @@ function partition(s: string): string[][] {
|
||||
};
|
||||
```
|
||||
|
||||
## C
|
||||
### C
|
||||
|
||||
```c
|
||||
char** path;
|
||||
@ -679,7 +677,7 @@ char*** partition(char* s, int* returnSize, int** returnColumnSizes){
|
||||
}
|
||||
```
|
||||
|
||||
## Swift
|
||||
### Swift
|
||||
|
||||
```swift
|
||||
func partition(_ s: String) -> [[String]] {
|
||||
@ -719,7 +717,7 @@ func partition(_ s: String) -> [[String]] {
|
||||
}
|
||||
```
|
||||
|
||||
## Rust
|
||||
### Rust
|
||||
|
||||
**回溯+函数判断回文串**
|
||||
```Rust
|
||||
@ -808,7 +806,7 @@ impl Solution {
|
||||
```
|
||||
|
||||
|
||||
## Scala
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
@ -855,3 +853,4 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -7,8 +7,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
> 别看本篇选的是组合总和III,而不是组合总和,本题和上一篇77.组合相比难度刚刚好!
|
||||
|
||||
# 216.组合总和III
|
||||
@ -30,12 +28,12 @@
|
||||
输入: k = 3, n = 9
|
||||
输出: [[1,2,6], [1,3,5], [2,3,4]]
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[和组合问题有啥区别?回溯算法如何剪枝?| LeetCode:216.组合总和III](https://www.bilibili.com/video/BV1wg411873x),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[和组合问题有啥区别?回溯算法如何剪枝?| LeetCode:216.组合总和III](https://www.bilibili.com/video/BV1wg411873x),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
|
||||
# 思路
|
||||
## 思路
|
||||
|
||||
本题就是在[1,2,3,4,5,6,7,8,9]这个集合中找到和为n的k个数的组合。
|
||||
|
||||
@ -54,7 +52,7 @@
|
||||
图中,可以看出,只有最后取到集合(1,3)和为4 符合条件。
|
||||
|
||||
|
||||
## 回溯三部曲
|
||||
### 回溯三部曲
|
||||
|
||||
* **确定递归函数参数**
|
||||
|
||||
@ -165,7 +163,7 @@ public:
|
||||
};
|
||||
```
|
||||
|
||||
## 剪枝
|
||||
### 剪枝
|
||||
|
||||
这道题目,剪枝操作其实是很容易想到了,想必大家看上面的树形图的时候已经想到了。
|
||||
|
||||
@ -238,7 +236,7 @@ public:
|
||||
* 时间复杂度: O(n * 2^n)
|
||||
* 空间复杂度: O(n)
|
||||
|
||||
# 总结
|
||||
## 总结
|
||||
|
||||
开篇就介绍了本题与[77.组合](https://programmercarl.com/0077.组合.html)的区别,相对来说加了元素总和的限制,如果做完[77.组合](https://programmercarl.com/0077.组合.html)再做本题在合适不过。
|
||||
|
||||
@ -249,10 +247,10 @@ public:
|
||||
|
||||
|
||||
|
||||
# 其他语言版本
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
## Java
|
||||
### Java
|
||||
|
||||
模板方法
|
||||
|
||||
@ -358,7 +356,7 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
## Python
|
||||
### Python
|
||||
|
||||
```py
|
||||
class Solution:
|
||||
@ -383,7 +381,7 @@ class Solution:
|
||||
|
||||
```
|
||||
|
||||
## Go
|
||||
### Go
|
||||
|
||||
回溯+减枝
|
||||
|
||||
@ -418,7 +416,7 @@ func dfs(k, n int, start int, sum int) {
|
||||
}
|
||||
```
|
||||
|
||||
## javaScript
|
||||
### JavaScript
|
||||
|
||||
```js
|
||||
/**
|
||||
@ -455,7 +453,7 @@ var combinationSum3 = function(k, n) {
|
||||
};
|
||||
```
|
||||
|
||||
## TypeScript
|
||||
### TypeScript
|
||||
|
||||
```typescript
|
||||
function combinationSum3(k: number, n: number): number[][] {
|
||||
@ -479,7 +477,7 @@ function combinationSum3(k: number, n: number): number[][] {
|
||||
};
|
||||
```
|
||||
|
||||
## Rust
|
||||
### Rust
|
||||
|
||||
```Rust
|
||||
impl Solution {
|
||||
@ -516,7 +514,7 @@ impl Solution {
|
||||
}
|
||||
```
|
||||
|
||||
## C
|
||||
### C
|
||||
|
||||
```c
|
||||
int* path;
|
||||
@ -575,7 +573,7 @@ int** combinationSum3(int k, int n, int* returnSize, int** returnColumnSizes){
|
||||
}
|
||||
```
|
||||
|
||||
## Swift
|
||||
### Swift
|
||||
|
||||
```swift
|
||||
func combinationSum3(_ count: Int, _ targetSum: Int) -> [[Int]] {
|
||||
@ -607,7 +605,7 @@ func combinationSum3(_ count: Int, _ targetSum: Int) -> [[Int]] {
|
||||
}
|
||||
```
|
||||
|
||||
## Scala
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
|
@ -29,9 +29,11 @@
|
||||
* 输出:["JFK","ATL","JFK","SFO","ATL","SFO"]
|
||||
* 解释:另一种有效的行程是 ["JFK","SFO","ATL","JFK","ATL","SFO"]。但是它自然排序更大更靠后。
|
||||
|
||||
## 思路
|
||||
## 算法公开课
|
||||
|
||||
**如果对回溯算法基础还不了解的话,我还特意录制了一期视频:[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/)** 可以结合题解和视频一起看,希望对大家理解回溯算法有所帮助。
|
||||
**如果对回溯算法基础还不了解的话,我还特意录制了一期视频,[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/)** 可以结合题解和视频一起看,希望对大家理解回溯算法有所帮助。
|
||||
|
||||
## 思路
|
||||
|
||||
|
||||
这道题目还是很难的,之前我们用回溯法解决了如下问题:[组合问题](https://programmercarl.com/0077.组合.html),[分割问题](https://programmercarl.com/0093.复原IP地址.html),[子集问题](https://programmercarl.com/0078.子集.html),[排列问题](https://programmercarl.com/0046.全排列.html)。
|
||||
@ -53,7 +55,7 @@
|
||||
|
||||
针对以上问题我来逐一解答!
|
||||
|
||||
## 如何理解死循环
|
||||
### 如何理解死循环
|
||||
|
||||
对于死循环,我来举一个有重复机场的例子:
|
||||
|
||||
@ -61,7 +63,7 @@
|
||||
|
||||
为什么要举这个例子呢,就是告诉大家,出发机场和到达机场也会重复的,**如果在解题的过程中没有对集合元素处理好,就会死循环。**
|
||||
|
||||
## 该记录映射关系
|
||||
### 该记录映射关系
|
||||
|
||||
有多种解法,字母序靠前排在前面,让很多同学望而退步,如何该记录映射关系呢 ?
|
||||
|
||||
@ -90,7 +92,7 @@ unordered_map<string, map<string, int>> targets:unordered_map<出发机场, ma
|
||||
|
||||
**相当于说我不删,我就做一个标记!**
|
||||
|
||||
## 回溯法
|
||||
### 回溯法
|
||||
|
||||
这道题目我使用回溯法,那么下面按照我总结的回溯模板来:
|
||||
|
||||
@ -260,8 +262,8 @@ for (pair<string, int>target : targets[result[result.size() - 1]])
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
### java
|
||||
|
||||
### Java
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
private LinkedList<String> res;
|
||||
@ -346,7 +348,7 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
### python
|
||||
### Python
|
||||
回溯 使用used数组
|
||||
|
||||
```python
|
||||
@ -406,7 +408,7 @@ class Solution:
|
||||
path.pop() # 移除目的地
|
||||
return False # 没有找到有效行程
|
||||
|
||||
```
|
||||
```
|
||||
回溯 使用字典 逆序
|
||||
```python
|
||||
from collections import defaultdict
|
||||
@ -430,8 +432,8 @@ class Solution:
|
||||
self.backtracking(next_airport, targets, result) # 递归调用回溯函数进行深度优先搜索
|
||||
result.append(airport) # 将当前机场添加到行程路径中
|
||||
```
|
||||
|
||||
### GO
|
||||
|
||||
### Go
|
||||
```go
|
||||
type pair struct {
|
||||
target string
|
||||
@ -577,7 +579,7 @@ function findItinerary(tickets: string[][]): string[] {
|
||||
};
|
||||
```
|
||||
|
||||
### C语言
|
||||
### C
|
||||
|
||||
```C
|
||||
char **result;
|
||||
@ -638,7 +640,7 @@ char ** findItinerary(char *** tickets, int ticketsSize, int* ticketsColSize, in
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Swift
|
||||
|
||||
直接迭代tickets数组:
|
||||
@ -791,3 +793,4 @@ impl Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -23,9 +23,9 @@
|
||||
* 数组中的整数范围是 [-100,100]。
|
||||
* 给定数组中可能包含重复数字,相等的数字应该被视为递增的一种情况。
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[回溯算法精讲,树层去重与树枝去重 | LeetCode:491.递增子序列](https://www.bilibili.com/video/BV1EG4y1h78v/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[回溯算法精讲,树层去重与树枝去重 | LeetCode:491.递增子序列](https://www.bilibili.com/video/BV1EG4y1h78v/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
|
||||
## 思路
|
||||
@ -619,4 +619,3 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -8,7 +8,9 @@
|
||||
|
||||
> 20张树形结构图、14道精选回溯题目,21篇回溯法精讲文章,由浅入深,一气呵成,这是全网最强回溯算法总结!
|
||||
|
||||
# 回溯法理论基础
|
||||
# 回溯总结篇
|
||||
|
||||
## 回溯法理论基础
|
||||
|
||||
转眼间[「代码随想录」](https://img-blog.csdnimg.cn/20200815195519696.png)里已经分享连续讲解了21天的回溯算法,是时候做一个大总结了,本篇高能,需要花费很大的精力来看!
|
||||
|
||||
@ -51,10 +53,10 @@ void backtracking(参数) {
|
||||
|
||||
**事实证明这个模板会伴随整个回溯法系列!**
|
||||
|
||||
# 组合问题
|
||||
|
||||
## 组合问题
|
||||
|
||||
### 组合问题
|
||||
|
||||
在[回溯算法:求组合问题!](https://programmercarl.com/0077.组合.html)中,我们开始用回溯法解决第一道题目:组合问题。
|
||||
|
||||
我在文中开始的时候给大家列举k层for循环例子,进而得出都是同样是暴力解法,为什么要用回溯法!
|
||||
@ -82,9 +84,9 @@ void backtracking(参数) {
|
||||
**在for循环上做剪枝操作是回溯法剪枝的常见套路!** 后面的题目还会经常用到。
|
||||
|
||||
|
||||
## 组合总和
|
||||
### 组合总和
|
||||
|
||||
### 组合总和(一)
|
||||
#### 组合总和(一)
|
||||
|
||||
在[回溯算法:求组合总和!](https://programmercarl.com/0216.组合总和III.html)中,相当于 [回溯算法:求组合问题!](https://programmercarl.com/0077.组合.html)加了一个元素总和的限制。
|
||||
|
||||
@ -99,7 +101,7 @@ void backtracking(参数) {
|
||||
|
||||
所以剪枝的代码可以在for循环加上 `i <= 9 - (k - path.size()) + 1` 的限制!
|
||||
|
||||
### 组合总和(二)
|
||||
#### 组合总和(二)
|
||||
|
||||
在[回溯算法:求组合总和(二)](https://programmercarl.com/0039.组合总和.html)中讲解的组合总和问题,和[回溯算法:求组合问题!](https://programmercarl.com/0077.组合.html),[回溯算法:求组合总和!](https://programmercarl.com/0216.组合总和III.html)和区别是:本题没有数量要求,可以无限重复,但是有总和的限制,所以间接的也是有个数的限制。
|
||||
|
||||
@ -128,7 +130,7 @@ for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target;
|
||||

|
||||
|
||||
|
||||
### 组合总和(三)
|
||||
#### 组合总和(三)
|
||||
|
||||
在[回溯算法:求组合总和(三)](https://programmercarl.com/0040.组合总和II.html)中集合元素会有重复,但要求解集不能包含重复的组合。
|
||||
|
||||
@ -151,7 +153,7 @@ for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target;
|
||||
|
||||
对于去重,其实排列和子集问题也是一样的道理。
|
||||
|
||||
## 多个集合求组合
|
||||
### 多个集合求组合
|
||||
|
||||
在[回溯算法:电话号码的字母组合](https://programmercarl.com/0017.电话号码的字母组合.html)中,开始用多个集合来求组合,还是熟悉的模板题目,但是有一些细节。
|
||||
|
||||
@ -167,7 +169,7 @@ for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target;
|
||||
|
||||
其实本题不算难,但也处处是细节,还是要反复琢磨。
|
||||
|
||||
# 切割问题
|
||||
## 切割问题
|
||||
|
||||
在[回溯算法:分割回文串](https://programmercarl.com/0131.分割回文串.html)中,我们开始讲解切割问题,虽然最后代码看起来好像是一道模板题,但是从分析到学会套用这个模板,是比较难的。
|
||||
|
||||
@ -192,9 +194,9 @@ for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target;
|
||||

|
||||
|
||||
|
||||
# 子集问题
|
||||
## 子集问题
|
||||
|
||||
## 子集问题(一)
|
||||
### 子集问题(一)
|
||||
|
||||
在[回溯算法:求子集问题!](https://programmercarl.com/0078.子集.html)中讲解了子集问题,**在树形结构中子集问题是要收集所有节点的结果,而组合问题是收集叶子节点的结果**。
|
||||
|
||||
@ -219,7 +221,7 @@ if (startIndex >= nums.size()) { // 终止条件可以不加
|
||||
}
|
||||
```
|
||||
|
||||
## 子集问题(二)
|
||||
### 子集问题(二)
|
||||
|
||||
在[回溯算法:求子集问题(二)](https://programmercarl.com/0090.子集II.html)中,开始针对子集问题进行去重。
|
||||
|
||||
@ -229,7 +231,7 @@ if (startIndex >= nums.size()) { // 终止条件可以不加
|
||||
|
||||

|
||||
|
||||
## 递增子序列
|
||||
### 递增子序列
|
||||
|
||||
在[回溯算法:递增子序列](https://programmercarl.com/0491.递增子序列.html)中,处处都能看到子集的身影,但处处是陷阱,值得好好琢磨琢磨!
|
||||
|
||||
@ -247,9 +249,9 @@ if (startIndex >= nums.size()) { // 终止条件可以不加
|
||||
|
||||
**相信这个图胜过千言万语的解释了**。
|
||||
|
||||
# 排列问题
|
||||
## 排列问题
|
||||
|
||||
## 排列问题(一)
|
||||
### 排列问题(一)
|
||||
|
||||
[回溯算法:排列问题!](https://programmercarl.com/0046.全排列.html) 又不一样了。
|
||||
|
||||
@ -266,7 +268,7 @@ if (startIndex >= nums.size()) { // 终止条件可以不加
|
||||
* 每层都是从0开始搜索而不是startIndex
|
||||
* 需要used数组记录path里都放了哪些元素了
|
||||
|
||||
## 排列问题(二)
|
||||
### 排列问题(二)
|
||||
|
||||
排列问题也要去重了,在[回溯算法:排列问题(二)](https://programmercarl.com/0047.全排列II.html)中又一次强调了“树层去重”和“树枝去重”。
|
||||
|
||||
@ -290,7 +292,7 @@ if (startIndex >= nums.size()) { // 终止条件可以不加
|
||||
|
||||
本题used数组即是记录path里都放了哪些元素,同时也用来去重,一举两得。
|
||||
|
||||
# 去重问题
|
||||
## 去重问题
|
||||
|
||||
以上我都是统一使用used数组来去重的,其实使用set也可以用来去重!
|
||||
|
||||
@ -310,7 +312,7 @@ if (startIndex >= nums.size()) { // 终止条件可以不加
|
||||
|
||||
used数组可是全局变量,每层与每层之间公用一个used数组,所以空间复杂度是O(n + n),最终空间复杂度还是O(n)。
|
||||
|
||||
# 重新安排行程(图论额外拓展)
|
||||
## 重新安排行程(图论额外拓展)
|
||||
|
||||
之前说过,有递归的地方就有回溯,深度优先搜索也是用递归来实现的,所以往往伴随着回溯。
|
||||
|
||||
@ -327,9 +329,9 @@ used数组可是全局变量,每层与每层之间公用一个used数组,所
|
||||
本题其实是一道深度优先搜索的题目,但是我完全使用回溯法的思路来讲解这道题题目,**算是给大家拓展一下思维方式,其实深搜和回溯也是分不开的,毕竟最终都是用递归**。
|
||||
|
||||
|
||||
# 棋盘问题
|
||||
## 棋盘问题
|
||||
|
||||
## N皇后问题
|
||||
### N皇后问题
|
||||
|
||||
在[回溯算法:N皇后问题](https://programmercarl.com/0051.N皇后.html)中终于迎来了传说中的N皇后。
|
||||
|
||||
@ -349,7 +351,7 @@ used数组可是全局变量,每层与每层之间公用一个used数组,所
|
||||
|
||||
|
||||
|
||||
## 解数独问题
|
||||
### 解数独问题
|
||||
|
||||
在[回溯算法:解数独](https://programmercarl.com/0037.解数独.html)中要征服回溯法的最后一道山峰。
|
||||
|
||||
@ -373,7 +375,7 @@ used数组可是全局变量,每层与每层之间公用一个used数组,所
|
||||
|
||||
**这样,解数独这么难的问题也被我们攻克了**。
|
||||
|
||||
# 性能分析
|
||||
## 性能分析
|
||||
|
||||
**关于回溯算法的复杂度分析在网上的资料鱼龙混杂,一些所谓的经典面试书籍不讲回溯算法,算法书籍对这块也避而不谈,感觉就像是算法里模糊的边界**。
|
||||
|
||||
@ -410,7 +412,7 @@ N皇后问题分析:
|
||||
**一般说道回溯算法的复杂度,都说是指数级别的时间复杂度,这也算是一个概括吧!**
|
||||
|
||||
|
||||
# 总结
|
||||
## 总结
|
||||
|
||||
**[「代码随想录」](https://img-blog.csdnimg.cn/20200815195519696.png)历时21天,14道经典题目分析,20张树形图,21篇回溯法精讲文章,从组合到切割,从子集到排列,从棋盘问题到最后的复杂度分析**,至此收尾了。
|
||||
|
||||
@ -449,3 +451,4 @@ N皇后问题分析:
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -246,8 +246,7 @@ used数组可是全局变量,每层与每层之间公用一个used数组,所
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
### Java
|
||||
**47.全排列II**
|
||||
|
||||
|
||||
@ -350,7 +349,7 @@ class Solution {
|
||||
}
|
||||
}
|
||||
```
|
||||
Python:
|
||||
### Python
|
||||
|
||||
**90.子集II**
|
||||
|
||||
@ -432,7 +431,7 @@ class Solution:
|
||||
|
||||
```
|
||||
|
||||
JavaScript:
|
||||
### JavaScript
|
||||
|
||||
**90.子集II**
|
||||
|
||||
@ -510,7 +509,7 @@ function permuteUnique(nums) {
|
||||
};
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
### TypeScript
|
||||
|
||||
**90.子集II**
|
||||
|
||||
@ -592,7 +591,7 @@ function permuteUnique(nums: number[]): number[][] {
|
||||
};
|
||||
```
|
||||
|
||||
Rust:
|
||||
### Rust
|
||||
|
||||
**90.子集II**:
|
||||
|
||||
@ -713,3 +712,4 @@ impl Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -6,13 +6,19 @@
|
||||
|
||||
# 回溯算法理论基础
|
||||
|
||||
## 题目分类大纲如下:
|
||||
## 题目分类
|
||||
|
||||
<img src='https://code-thinking-1253855093.file.myqcloud.com/pics/20210219192050666.png' width=600 alt='回溯算法大纲'> </img>
|
||||
|
||||
可以配合我的B站视频:[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/) 一起学习!
|
||||
## 算法公开课
|
||||
|
||||
## 什么是回溯法
|
||||
|
||||
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/),相信结合视频再看本篇题解,更有助于大家对本题的理解。**
|
||||
|
||||
## 理论基础
|
||||
|
||||
### 什么是回溯法
|
||||
|
||||
回溯法也可以叫做回溯搜索法,它是一种搜索的方式。
|
||||
|
||||
@ -22,7 +28,7 @@
|
||||
|
||||
**所以以下讲解中,回溯函数也就是递归函数,指的都是一个函数**。
|
||||
|
||||
## 回溯法的效率
|
||||
### 回溯法的效率
|
||||
|
||||
回溯法的性能如何呢,这里要和大家说清楚了,**虽然回溯法很难,很不好理解,但是回溯法并不是什么高效的算法**。
|
||||
|
||||
@ -34,7 +40,7 @@
|
||||
|
||||
此时大家应该好奇了,都什么问题,这么牛逼,只能暴力搜索。
|
||||
|
||||
## 回溯法解决的问题
|
||||
### 回溯法解决的问题
|
||||
|
||||
回溯法,一般可以解决如下几种问题:
|
||||
|
||||
@ -55,7 +61,7 @@
|
||||
|
||||
记住组合无序,排列有序,就可以了。
|
||||
|
||||
## 如何理解回溯法
|
||||
### 如何理解回溯法
|
||||
|
||||
**回溯法解决的问题都可以抽象为树形结构**,是的,我指的是所有回溯法的问题都可以抽象为树形结构!
|
||||
|
||||
@ -66,7 +72,7 @@
|
||||
这块可能初学者还不太理解,后面的回溯算法解决的所有题目中,我都会强调这一点并画图举相应的例子,现在有一个印象就行。
|
||||
|
||||
|
||||
## 回溯法模板
|
||||
### 回溯法模板
|
||||
|
||||
这里给出Carl总结的回溯算法模板。
|
||||
|
||||
@ -173,3 +179,4 @@ void backtracking(参数) {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
Reference in New Issue
Block a user