diff --git a/README.md b/README.md index e5eb97bc..d3b4fe66 100644 --- a/README.md +++ b/README.md @@ -386,7 +386,7 @@ * [图论:深度优先搜索理论基础](./problems/图论深搜理论基础.md) * [图论:797.所有可能的路径](./problems/0797.所有可能的路径.md) -* [图论:广度优先搜索理论基础](./problems/图论广索理论基础.md) +* [图论:广度优先搜索理论基础](./problems/图论广搜理论基础.md) * [图论:200.岛屿数量.深搜版](./problems/0200.岛屿数量.深搜版.md) * [图论:200.岛屿数量.广搜版](./problems/0200.岛屿数量.广搜版.md) * [图论:695.岛屿的最大面积](./problems/0695.岛屿的最大面积.md) diff --git a/problems/0001.两数之和.md b/problems/0001.两数之和.md index ca62e3ed..bf1e173e 100644 --- a/problems/0001.两数之和.md +++ b/problems/0001.两数之和.md @@ -5,7 +5,7 @@
参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!
-## 1. 两数之和 +# 1. 两数之和 [力扣题目链接](https://leetcode.cn/problems/two-sum/) @@ -21,11 +21,13 @@ 所以返回 [0, 1] +## 算法公开课 + +**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[梦开始的地方,Leetcode:1.两数之和](https://www.bilibili.com/video/BV1aT41177mK),相信结合视频再看本篇题解,更有助于大家对本题的理解**。 + ## 思路 -建议看一下我录的这期视频:[梦开始的地方,Leetcode:1.两数之和](https://www.bilibili.com/video/BV1aT41177mK),结合本题解来学习,事半功倍。 - 很明显暴力的解法是两层for循环查找,时间复杂度是O(n^2)。 建议大家做这道题目之前,先做一下这两道 @@ -128,8 +130,8 @@ public: ## 其他语言版本 +### Java: -Java: ```java public int[] twoSum(int[] nums, int target) { int[] res = new int[2]; @@ -150,8 +152,9 @@ public int[] twoSum(int[] nums, int target) { } ``` -Python: +### Python: (版本一) 使用字典 + ```python class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: @@ -160,7 +163,7 @@ class Solution: for index, value in enumerate(nums): if target - value in records: # 遍历当前元素,并在map中寻找是否有匹配的key return [records[target- value], index] - records[value] = index # 遍历当前元素,并在map中寻找是否有匹配的key + records[value] = index # 如果没找到匹配对,就把访问过的元素和下标加入到map中 return [] ``` (版本二)使用集合 @@ -211,7 +214,7 @@ class Solution: return [i,j] ``` -Go: +### Go: ```go // 暴力解法 @@ -242,7 +245,7 @@ func twoSum(nums []int, target int) []int { } ``` -Rust +### Rust: ```rust use std::collections::HashMap; @@ -263,9 +266,7 @@ impl Solution { } } ``` -Rust - -``` +```rust use std::collections::HashMap; impl Solution { @@ -284,7 +285,7 @@ impl Solution { } ``` -Javascript +### Javascript: ```javascript var twoSum = function (nums, target) { @@ -299,7 +300,7 @@ var twoSum = function (nums, target) { }; ``` -TypeScript: +### TypeScript: ```typescript function twoSum(nums: number[], target: number): number[] { @@ -317,7 +318,7 @@ function twoSum(nums: number[], target: number): number[] { }; ``` -php +### php: ```php function twoSum(array $nums, int $target): array @@ -337,7 +338,8 @@ function twoSum(array $nums, int $target): array } ``` -Swift: +### Swift: + ```swift func twoSum(_ nums: [Int], _ target: Int) -> [Int] { // 值: 下标 @@ -353,8 +355,8 @@ func twoSum(_ nums: [Int], _ target: Int) -> [Int] { } ``` +### Scala: -Scala: ```scala object Solution { // 导入包 @@ -377,7 +379,8 @@ object Solution { } ``` -C#: +### C#: + ```csharp public class Solution { public int[] TwoSum(int[] nums, int target) { @@ -396,7 +399,8 @@ public class Solution { } ``` -Dart: +### Dart: + ```dart List
+
diff --git a/problems/0017.电话号码的字母组合.md b/problems/0017.电话号码的字母组合.md
index cf5e4520..b3ba1e5e 100644
--- a/problems/0017.电话号码的字母组合.md
+++ b/problems/0017.电话号码的字母组合.md
@@ -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 {
+
diff --git a/problems/0018.四数之和.md b/problems/0018.四数之和.md
index a4d41d9b..28c20b7a 100644
--- a/problems/0018.四数之和.md
+++ b/problems/0018.四数之和.md
@@ -27,9 +27,11 @@
[-2, 0, 0, 2]
]
-# 思路
+## 算法公开课
-针对本题,我录制了视频讲解:[难在去重和剪枝!| LeetCode:18. 四数之和](https://www.bilibili.com/video/BV1DS4y147US),结合本题解一起看,事半功倍!
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[难在去重和剪枝!| LeetCode:18. 四数之和](https://www.bilibili.com/video/BV1DS4y147US),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
+
+## 思路
四数之和,和[15.三数之和](https://programmercarl.com/0015.三数之和.html)是一个思路,都是使用双指针法, 基本解法就是在[15.三数之和](https://programmercarl.com/0015.三数之和.html) 的基础上再套一层for循环。
@@ -141,22 +143,16 @@ if (nums[k] + nums[i] > target && nums[k] + nums[i] >= 0) {
if (nums[k] + nums[i] > target && nums[i] >= 0) {
break;
}
-```
+```
因为只要 nums[k] + nums[i] > target,那么 nums[i] 后面的数都是正数的话,就一定 不符合条件了。
不过这种剪枝 其实有点 小绕,大家能够理解 文章给的完整代码的剪枝 就够了。
-
-
-
-
-
-
## 其他语言版本
+### Java:
-Java:
```Java
class Solution {
public List
+
diff --git a/problems/0020.有效的括号.md b/problems/0020.有效的括号.md
index 213d61b7..045c79ee 100644
--- a/problems/0020.有效的括号.md
+++ b/problems/0020.有效的括号.md
@@ -39,12 +39,13 @@
* 输入: "{[]}"
* 输出: true
-# 思路
+## 算法公开课
-《代码随想录》算法视频公开课:[栈的拿手好戏!| LeetCode:20. 有效的括号](https://www.bilibili.com/video/BV1AF411w78g),相信结合视频在看本篇题解,更有助于大家对链表的理解。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[栈的拿手好戏!| LeetCode:20. 有效的括号](https://www.bilibili.com/video/BV1AF411w78g),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
+## 思路
-## 题外话
+### 题外话
**括号匹配是使用栈解决的经典问题。**
@@ -68,7 +69,7 @@ cd a/b/c/../../
这里我就不过多展开了,先来看题。
-## 进入正题
+### 进入正题
由于栈结构的特殊性,非常适合做对称匹配类的题目。
@@ -143,8 +144,8 @@ public:
## 其他语言版本
+### Java:
-Java:
```Java
class Solution {
public boolean isValid(String s) {
@@ -171,7 +172,8 @@ class Solution {
}
```
-Python:
+### Python:
+
```python
# 方法一,仅使用栈,更省空间
class Solution:
@@ -213,7 +215,8 @@ class Solution:
return True if not stack else False
```
-Go:
+### Go:
+
```Go
func isValid(s string) bool {
hash := map[byte]byte{')':'(', ']':'[', '}':'{'}
@@ -235,7 +238,8 @@ func isValid(s string) bool {
}
```
-Ruby:
+### Ruby:
+
```ruby
def is_valid(strs)
symbol_map = {')' => '(', '}' => '{', ']' => '['}
@@ -253,7 +257,8 @@ def is_valid(strs)
end
```
-Javascript:
+### Javascript:
+
```javascript
var isValid = function (s) {
const stack = [];
@@ -296,7 +301,7 @@ var isValid = function(s) {
};
```
-TypeScript:
+### TypeScript:
版本一:普通版
@@ -348,7 +353,7 @@ function isValid(s: string): boolean {
};
```
-Swift
+### Swift:
```swift
func isValid(_ s: String) -> Bool {
@@ -373,7 +378,8 @@ func isValid(_ s: String) -> Bool {
}
```
-C:
+### C:
+
```C
//辅助函数:判断栈顶元素与输入的括号是否为一对。若不是,则返回False
int notMatch(char par, char* stack, int stackTop) {
@@ -414,8 +420,8 @@ bool isValid(char * s){
}
```
+### C#:
-C#:
```csharp
public class Solution {
public bool IsValid(string s) {
@@ -447,7 +453,8 @@ public class Solution {
}
```
-PHP:
+### PHP:
+
```php
// https://www.php.net/manual/zh/class.splstack.php
class Solution
@@ -475,8 +482,8 @@ class Solution
}
```
+### Scala:
-Scala:
```scala
object Solution {
import scala.collection.mutable
@@ -499,7 +506,7 @@ object Solution {
}
```
-rust:
+### Rust:
```rust
impl Solution {
diff --git a/problems/0028.实现strStr.md b/problems/0028.实现strStr.md
index ac984d1a..53b57fd5 100644
--- a/problems/0028.实现strStr.md
+++ b/problems/0028.实现strStr.md
@@ -28,7 +28,7 @@
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。
-# 思路
+## 思路
本题是KMP 经典题目。
@@ -60,13 +60,13 @@ KMP的经典思想就是:**当出现字符串不匹配时,可以记录一部
读完本篇可以顺便把leetcode上28.实现strStr()题目做了。
-# 什么是KMP
+### 什么是KMP
说到KMP,先说一下KMP这个名字是怎么来的,为什么叫做KMP呢。
因为是由这三位学者发明的:Knuth,Morris和Pratt,所以取了三位学者名字的首字母。所以叫做KMP
-# KMP有什么用
+### KMP有什么用
KMP主要应用在字符串匹配上。
@@ -84,7 +84,7 @@ KMP的主要思想是**当出现字符串不匹配时,可以知道一部分之
下面Carl就带大家把KMP的精髓,next数组弄清楚。
-# 什么是前缀表
+### 什么是前缀表
写过KMP的同学,一定都写过next数组,那么这个next数组究竟是个啥呢?
@@ -122,7 +122,7 @@ next数组就是一个前缀表(prefix table)。
那么什么是前缀表:**记录下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀。**
-# 最长公共前后缀?
+### 最长公共前后缀
文章中字符串的**前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串**。
@@ -144,7 +144,7 @@ next数组就是一个前缀表(prefix table)。
等等.....。
-# 为什么一定要用前缀表
+### 为什么一定要用前缀表
这就是前缀表,那为啥就能告诉我们 上次匹配的位置,并跳过去呢?
@@ -163,7 +163,7 @@ next数组就是一个前缀表(prefix table)。
**很多介绍KMP的文章或者视频并没有把为什么要用前缀表?这个问题说清楚,而是直接默认使用前缀表。**
-# 如何计算前缀表
+### 如何计算前缀表
接下来就要说一说怎么计算前缀表。
@@ -205,7 +205,7 @@ next数组就是一个前缀表(prefix table)。
最后就在文本串中找到了和模式串匹配的子串了。
-# 前缀表与next数组
+### 前缀表与next数组
很多KMP算法的时间都是使用next数组来做回退操作,那么next数组与前缀表有什么关系呢?
@@ -217,7 +217,7 @@ next数组就可以是前缀表,但是很多实现都是把前缀表统一减
后面我会提供两种不同的实现代码,大家就明白了。
-# 使用next数组来匹配
+### 使用next数组来匹配
**以下我们以前缀表统一减一之后的next数组来做演示**。
@@ -229,7 +229,7 @@ next数组就可以是前缀表,但是很多实现都是把前缀表统一减

-# 时间复杂度分析
+### 时间复杂度分析
其中n为文本串长度,m为模式串长度,因为在匹配的过程中,根据前缀表不断调整匹配的位置,可以看出匹配的过程是O(n),之前还要单独生成next数组,时间复杂度是O(m)。所以整个KMP算法的时间复杂度是O(n+m)的。
@@ -239,7 +239,7 @@ next数组就可以是前缀表,但是很多实现都是把前缀表统一减
都知道使用KMP算法,一定要构造next数组。
-# 构造next数组
+### 构造next数组
我们定义一个函数getNext来构建next数组,函数参数为指向next数组的指针,和一个字符串。 代码如下:
@@ -338,7 +338,7 @@ void getNext(int* next, const string& s){
得到了next数组之后,就要用这个来做匹配了。
-# 使用next数组来做匹配
+### 使用next数组来做匹配
在文本串s里 找是否出现过模式串t。
@@ -403,7 +403,7 @@ for (int i = 0; i < s.size(); i++) { // 注意i就从0开始
此时所有逻辑的代码都已经写出来了,力扣 28.实现strStr 题目的整体代码如下:
-# 前缀表统一减一 C++代码实现
+### 前缀表统一减一 C++代码实现
```CPP
class Solution {
@@ -447,7 +447,7 @@ public:
* 时间复杂度: O(n + m)
* 空间复杂度: O(m), 只需要保存字符串needle的前缀表
-# 前缀表(不减一)C++实现
+### 前缀表(不减一)C++实现
那么前缀表就不减一了,也不右移的,到底行不行呢?
@@ -546,7 +546,7 @@ public:
* 空间复杂度: O(m)
-# 总结
+## 总结
我们介绍了什么是KMP,KMP可以解决什么问题,然后分析KMP算法里的next数组,知道了next数组就是前缀表,再分析为什么要是前缀表而不是什么其他表。
@@ -563,8 +563,7 @@ public:
## 其他语言版本
-
-Java:
+### Java:
```Java
class Solution {
@@ -691,8 +690,9 @@ class Solution {
}
```
-Python3:
+### Python3:
(版本一)前缀表(减一)
+
```python
class Solution:
def getNext(self, next, s):
@@ -781,9 +781,9 @@ class Solution:
def strStr(self, haystack: str, needle: str) -> int:
return haystack.find(needle)
-```
+```
-Go:
+### Go:
```go
// 方法一:前缀表使用减1实现
@@ -871,7 +871,7 @@ func strStr(haystack string, needle string) int {
}
```
-JavaScript版本
+### JavaScript:
> 前缀表统一减一
@@ -959,7 +959,7 @@ var strStr = function (haystack, needle) {
};
```
-TypeScript版本:
+### TypeScript:
> 前缀表统一减一
@@ -1036,7 +1036,7 @@ function strStr(haystack: string, needle: string): number {
}
```
-Swift 版本
+### Swift:
> 前缀表统一减一
@@ -1196,7 +1196,7 @@ func strStr(_ haystack: String, _ needle: String) -> Int {
```
-PHP:
+### PHP:
> 前缀表统一减一
```php
@@ -1272,7 +1272,7 @@ function getNext(&$next, $s){
}
```
-Rust:
+### Rust:
> 前缀表统一不减一
```Rust
@@ -1362,4 +1362,3 @@ impl Solution {
-
diff --git a/problems/0037.解数独.md b/problems/0037.解数独.md
index 6edd3c5b..1763063e 100644
--- a/problems/0037.解数独.md
+++ b/problems/0037.解数独.md
@@ -6,8 +6,7 @@
参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!
- -如果对回溯法理论还不清楚的同学,可以先看这个视频[视频来了!!带你学透回溯算法(理论篇)](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 {
+
diff --git a/problems/0039.组合总和.md b/problems/0039.组合总和.md
index 4d9466c3..2a36ce5a 100644
--- a/problems/0039.组合总和.md
+++ b/problems/0039.组合总和.md
@@ -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 {
+
diff --git a/problems/0040.组合总和II.md b/problems/0040.组合总和II.md
index 9094020e..33e4a46f 100644
--- a/problems/0040.组合总和II.md
+++ b/problems/0040.组合总和II.md
@@ -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 {
+
diff --git a/problems/0042.接雨水.md b/problems/0042.接雨水.md
index db66095d..833a7613 100644
--- a/problems/0042.接雨水.md
+++ b/problems/0042.接雨水.md
@@ -926,6 +926,56 @@ int trap(int* height, int heightSize) {
* 空间复杂度 O(1)
+Rust
+
+双指针
+
+```rust
+impl Solution {
+ pub fn trap(height: Vec
diff --git a/problems/0045.跳跃游戏II.md b/problems/0045.跳跃游戏II.md
index 2f0349b2..02c8e486 100644
--- a/problems/0045.跳跃游戏II.md
+++ b/problems/0045.跳跃游戏II.md
@@ -25,9 +25,9 @@
说明:
假设你总是可以到达数组的最后一个位置。
-# 视频讲解
+## 算法公开课
-**《代码随想录》算法视频公开课:[贪心算法,最少跳几步还得看覆盖范围 | LeetCode: 45.跳跃游戏 II](https://www.bilibili.com/video/BV1Y24y1r7XZ),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[贪心算法,最少跳几步还得看覆盖范围 | LeetCode: 45.跳跃游戏 II](https://www.bilibili.com/video/BV1Y24y1r7XZ),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
## 思路
@@ -53,7 +53,7 @@
**图中覆盖范围的意义在于,只要红色的区域,最多两步一定可以到!(不用管具体怎么跳,反正一定可以跳到)**
-## 方法一
+### 方法一
从图中可以看出来,就是移动下标达到了当前覆盖的最远距离下标时,步数就要加一,来增加覆盖距离。最后的步数就是最少步数。
@@ -90,7 +90,7 @@ public:
* 空间复杂度: O(1)
-## 方法二
+### 方法二
依然是贪心,思路和方法一差不多,代码可以简洁一些。
@@ -469,3 +469,4 @@ impl Solution {
+
diff --git a/problems/0046.全排列.md b/problems/0046.全排列.md
index de1af642..1f5263a7 100644
--- a/problems/0046.全排列.md
+++ b/problems/0046.全排列.md
@@ -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 {
+
diff --git a/problems/0047.全排列II.md b/problems/0047.全排列II.md
index afede33a..4fed8a5c 100644
--- a/problems/0047.全排列II.md
+++ b/problems/0047.全排列II.md
@@ -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 {
+
diff --git a/problems/0051.N皇后.md b/problems/0051.N皇后.md
index 13cdafb8..6bc4fa78 100644
--- a/problems/0051.N皇后.md
+++ b/problems/0051.N皇后.md
@@ -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 {
+
diff --git a/problems/0052.N皇后II.md b/problems/0052.N皇后II.md
index 90b920ba..29c2b588 100644
--- a/problems/0052.N皇后II.md
+++ b/problems/0052.N皇后II.md
@@ -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;
diff --git a/problems/0053.最大子序和(动态规划).md b/problems/0053.最大子序和(动态规划).md
index 6f3b3686..f1b64709 100644
--- a/problems/0053.最大子序和(动态规划).md
+++ b/problems/0053.最大子序和(动态规划).md
@@ -17,7 +17,7 @@
## 算法公开课
-**《代码随想录》算法视频公开课:[看起来复杂,其实是简单动态规划 | LeetCode:53.最大子序和](https://www.bilibili.com/video/BV19V4y1F7b5),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[看起来复杂,其实是简单动态规划 | LeetCode:53.最大子序和](https://www.bilibili.com/video/BV19V4y1F7b5),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
## 思路
@@ -97,8 +97,8 @@ public:
## 其他语言版本
+### Java:
-Java:
```java
/**
* 1.dp[i]代表当前下标对应的最大值
@@ -140,7 +140,8 @@ class Solution {
}
```
-Python:
+### Python:
+
```python
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
@@ -153,7 +154,8 @@ class Solution:
return result
```
-Go:
+### Go:
+
```Go
// solution
// 1, dp
@@ -184,7 +186,7 @@ func max(a,b int) int{
}
```
-JavaScript:
+### JavaScript:
```javascript
const maxSubArray = nums => {
@@ -203,8 +205,7 @@ const maxSubArray = nums => {
};
```
-
-Scala:
+### Scala:
```scala
object Solution {
@@ -221,7 +222,7 @@ object Solution {
}
```
-TypeScript:
+### TypeScript:
```typescript
function maxSubArray(nums: number[]): number {
@@ -244,3 +245,4 @@ function maxSubArray(nums: number[]): number {
+
diff --git a/problems/0055.跳跃游戏.md b/problems/0055.跳跃游戏.md
index e54c2034..bedb09ab 100644
--- a/problems/0055.跳跃游戏.md
+++ b/problems/0055.跳跃游戏.md
@@ -26,9 +26,9 @@
- 输出: false
- 解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。
-# 视频讲解
+## 算法公开课
-**《代码随想录》算法视频公开课:[贪心算法,怎么跳跃不重要,关键在覆盖范围 | LeetCode:55.跳跃游戏](https://www.bilibili.com/video/BV1VG4y1X7kB),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[贪心算法,怎么跳跃不重要,关键在覆盖范围 | LeetCode:55.跳跃游戏](https://www.bilibili.com/video/BV1VG4y1X7kB),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
## 思路
diff --git a/problems/0056.合并区间.md b/problems/0056.合并区间.md
index 8705f840..95781b1a 100644
--- a/problems/0056.合并区间.md
+++ b/problems/0056.合并区间.md
@@ -22,9 +22,9 @@
* 解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。
* 注意:输入类型已于2019年4月15日更改。 请重置默认代码定义以获取新方法签名。
-# 视频讲解
+## 算法公开课
-**《代码随想录》算法视频公开课:[贪心算法,合并区间有细节!LeetCode:56.合并区间](https://www.bilibili.com/video/BV1wx4y157nD),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[贪心算法,合并区间有细节!LeetCode:56.合并区间](https://www.bilibili.com/video/BV1wx4y157nD),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
## 思路
@@ -341,3 +341,4 @@ impl Solution {
+
diff --git a/problems/0059.螺旋矩阵II.md b/problems/0059.螺旋矩阵II.md
index f03fcdad..73e9e4da 100644
--- a/problems/0059.螺旋矩阵II.md
+++ b/problems/0059.螺旋矩阵II.md
@@ -688,6 +688,58 @@ public class Solution {
}
```
+### Ruby#:
+```ruby
+def generate_matrix(n)
+ result = Array.new(n) { Array.new(n, 0) }
+ #循环次数
+ loop_times = 0
+ #步长
+ step = n - 1
+ val = 1
+
+
+ while loop_times < n / 2
+ #模拟从左向右
+ for i in 0..step - 1
+ #行数不变,列数变
+ result[loop_times][i+loop_times] = val
+ val += 1
+ end
+
+ #模拟从上到下
+ for i in 0..step - 1
+ #列数不变,行数变
+ result[i+loop_times][n-loop_times-1] = val
+ val += 1
+ end
+
+ #模拟从右到左
+ for i in 0..step - 1
+ #行数不变,列数变
+ result[n-loop_times-1][n-loop_times-i-1] = val
+ val += 1
+ end
+
+ #模拟从下到上
+ for i in 0..step - 1
+ #列数不变,行数变
+ result[n-loop_times-i-1][loop_times] = val
+ val += 1
+ end
+
+ loop_times += 1
+ step -= 2
+ end
+
+ #如果是奇数,则填充最后一个元素
+ result[n/2][n/2] = n**2 if n % 2
+
+ return result
+
+end
+```
+
diff --git a/problems/0070.爬楼梯.md b/problems/0070.爬楼梯.md
index 1b24e491..1a1f7e31 100644
--- a/problems/0070.爬楼梯.md
+++ b/problems/0070.爬楼梯.md
@@ -29,9 +29,9 @@
* 1 阶 + 2 阶
* 2 阶 + 1 阶
-# 视频讲解
+## 算法公开课
-**《代码随想录》算法视频公开课:[带你学透动态规划-爬楼梯|LeetCode:70.爬楼梯)](https://www.bilibili.com/video/BV17h411h7UH),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[带你学透动态规划-爬楼梯|LeetCode:70.爬楼梯)](https://www.bilibili.com/video/BV17h411h7UH),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
## 思路
@@ -522,3 +522,4 @@ impl Solution {
+
diff --git a/problems/0070.爬楼梯完全背包版本.md b/problems/0070.爬楼梯完全背包版本.md
index 8c85985f..4ca7a371 100644
--- a/problems/0070.爬楼梯完全背包版本.md
+++ b/problems/0070.爬楼梯完全背包版本.md
@@ -127,8 +127,8 @@ public:
## 其他语言版本
+### Java:
-Java:
```java
class Solution {
public int climbStairs(int n) {
@@ -148,7 +148,7 @@ class Solution {
}
```
-Python3:
+### Python3:
```python
@@ -166,8 +166,8 @@ class Solution:
return dp[n]
```
+### Go:
-Go:
```go
func climbStairs(n int) int {
//定义
@@ -189,7 +189,8 @@ func climbStairs(n int) int {
}
```
-JavaScript:
+### JavaScript:
+
```javascript
var climbStairs = function(n) {
const dp = new Array(n + 1).fill(0);
@@ -206,7 +207,7 @@ var climbStairs = function(n) {
};
```
-TypeScript:
+### TypeScript:
```typescript
function climbStairs(n: number): number {
@@ -226,7 +227,7 @@ function climbStairs(n: number): number {
};
```
-Rust:
+### Rust:
```rust
impl Solution {
@@ -250,4 +251,3 @@ impl Solution {
-
diff --git a/problems/0072.编辑距离.md b/problems/0072.编辑距离.md
index 703e8913..1ed9a860 100644
--- a/problems/0072.编辑距离.md
+++ b/problems/0072.编辑距离.md
@@ -40,8 +40,8 @@ exection -> execution (插入 'u')
* 0 <= word1.length, word2.length <= 500
* word1 和 word2 由小写英文字母组成
-# 算法公开课
-**《代码随想录》算法视频公开课:[动态规划终极绝杀! LeetCode:72.编辑距离](https://www.bilibili.com/video/BV1we4y157wB/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
+## 算法公开课
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划终极绝杀! LeetCode:72.编辑距离](https://www.bilibili.com/video/BV1we4y157wB/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
## 思路
@@ -227,8 +227,8 @@ public:
## 其他语言版本
+### Java:
-Java:
```java
public int minDistance(String word1, String word2) {
int m = word1.length();
@@ -256,7 +256,8 @@ public int minDistance(String word1, String word2) {
}
```
-Python:
+### Python:
+
```python
class Solution:
def minDistance(self, word1: str, word2: str) -> int:
@@ -274,7 +275,8 @@ class Solution:
return dp[-1][-1]
```
-Go:
+### Go:
+
```Go
func minDistance(word1 string, word2 string) int {
m, n := len(word1), len(word2)
@@ -310,8 +312,8 @@ func Min(args ...int) int {
}
```
+### Javascript:
-Javascript:
```javascript
const minDistance = (word1, word2) => {
let dp = Array.from(Array(word1.length + 1), () => Array(word2.length+1).fill(0));
@@ -338,7 +340,7 @@ const minDistance = (word1, word2) => {
};
```
-TypeScript:
+### TypeScript:
```typescript
function minDistance(word1: string, word2: string): number {
@@ -373,7 +375,7 @@ function minDistance(word1: string, word2: string): number {
};
```
-C:
+### C:
```c
@@ -405,3 +407,4 @@ int minDistance(char * word1, char * word2){
+
diff --git a/problems/0077.组合.md b/problems/0077.组合.md
index 444e15ce..8d448739 100644
--- a/problems/0077.组合.md
+++ b/problems/0077.组合.md
@@ -5,10 +5,6 @@
参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!
- - - - # 第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,13 +340,35 @@ public: - - ## 其他语言版本 -### Java: +### Java: +未剪枝优化 +```java +class Solution { + List
+
diff --git a/problems/0077.组合优化.md b/problems/0077.组合优化.md
index 3926d006..9577d65f 100644
--- a/problems/0077.组合优化.md
+++ b/problems/0077.组合优化.md
@@ -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
+
diff --git a/problems/0078.子集.md b/problems/0078.子集.md
index 21009f6a..5f3654de 100644
--- a/problems/0078.子集.md
+++ b/problems/0078.子集.md
@@ -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
+
diff --git a/problems/0084.柱状图中最大的矩形.md b/problems/0084.柱状图中最大的矩形.md
index f9a83508..bc82a860 100644
--- a/problems/0084.柱状图中最大的矩形.md
+++ b/problems/0084.柱状图中最大的矩形.md
@@ -670,6 +670,61 @@ function largestRectangleArea(heights: number[]): number {
```
+Rust
+
+双指针预处理
+```rust
+
+impl Solution {
+ pub fn largest_rectangle_area(v: Vec参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!
- - # 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 {
+
diff --git a/problems/0093.复原IP地址.md b/problems/0093.复原IP地址.md
index 55e57dde..59cd92da 100644
--- a/problems/0093.复原IP地址.md
+++ b/problems/0093.复原IP地址.md
@@ -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 {
+
diff --git a/problems/0098.验证二叉搜索树.md b/problems/0098.验证二叉搜索树.md
index 95b657a5..a48ec065 100644
--- a/problems/0098.验证二叉搜索树.md
+++ b/problems/0098.验证二叉搜索树.md
@@ -20,18 +20,18 @@

-# 视频讲解
+## 算法公开课
-**《代码随想录》算法视频公开课:[你对二叉搜索树了解的还不够! | LeetCode:98.验证二叉搜索树](https://www.bilibili.com/video/BV18P411n7Q4),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[你对二叉搜索树了解的还不够! | LeetCode:98.验证二叉搜索树](https://www.bilibili.com/video/BV18P411n7Q4),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
-# 思路
+## 思路
要知道中序遍历下,输出的二叉搜索树节点的数值是有序序列。
有了这个特性,**验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。**
-## 递归法
+### 递归法
可以递归中序遍历将二叉搜索树转变成一个数组,代码如下:
@@ -211,7 +211,7 @@ public:
最后这份代码看上去整洁一些,思路也清晰。
-## 迭代法
+### 迭代法
可以用迭代法模拟二叉树中序遍历,对前中后序迭代法生疏的同学可以看这两篇[二叉树:听说递归能做的,栈也能做!](https://programmercarl.com/二叉树的迭代遍历.html),[二叉树:前中后序迭代方式统一写法](https://programmercarl.com/二叉树的统一迭代法.html)
@@ -245,7 +245,7 @@ public:
在[二叉树:二叉搜索树登场!](https://programmercarl.com/0700.二叉搜索树中的搜索.html)中我们分明写出了痛哭流涕的简洁迭代法,怎么在这里不行了呢,因为本题是要验证二叉搜索树啊。
-# 总结
+## 总结
这道题目是一个简单题,但对于没接触过的同学还是有难度的。
@@ -254,10 +254,10 @@ public:
只要把基本类型的题目都做过,总结过之后,思路自然就开阔了。
-# 其他语言版本
+## 其他语言版本
-## Java
+### Java
```Java
//使用統一迭代法
@@ -369,7 +369,7 @@ class Solution {
}
```
-## Python
+### Python
递归法(版本一)利用中序递增性质,转换成数组
```python
@@ -479,7 +479,7 @@ class Solution:
```
-## Go
+### Go
```Go
func isValidBST(root *TreeNode) bool {
@@ -526,7 +526,7 @@ func isValidBST(root *TreeNode) bool {
}
```
-## JavaScript
+### JavaScript
辅助数组解决
@@ -595,7 +595,7 @@ var isValidBST = function (root) {
};
```
-## TypeScript
+### TypeScript
> 辅助数组解决:
@@ -637,7 +637,7 @@ function isValidBST(root: TreeNode | null): boolean {
};
```
-## Scala
+### Scala
辅助数组解决:
```scala
@@ -682,7 +682,7 @@ object Solution {
}
```
-## rust
+### Rust
递归:
@@ -735,3 +735,4 @@ impl Solution {
+
diff --git a/problems/0101.对称二叉树.md b/problems/0101.对称二叉树.md
index 4418c62d..36b39740 100644
--- a/problems/0101.对称二叉树.md
+++ b/problems/0101.对称二叉树.md
@@ -13,9 +13,11 @@

-# 思路
+## 算法公开课
-《代码随想录》算法视频公开课:[同时操作两个二叉树 | LeetCode:101. 对称二叉树](https://www.bilibili.com/video/BV1ue4y1Y7Mf),相信结合视频在看本篇题解,更有助于大家对本题的理解。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[同时操作两个二叉树 | LeetCode:101. 对称二叉树](https://www.bilibili.com/video/BV1ue4y1Y7Mf), 相信结合视频再看本篇题解,更有助于大家对本题的理解**。
+
+## 思路
**首先想清楚,判断对称二叉树要比较的是哪两个节点,要比较的可不是左右节点!**
@@ -41,7 +43,7 @@
那么我们先来看看递归法的代码应该怎么写。
-## 递归法
+### 递归法
递归三部曲
@@ -159,13 +161,13 @@ public:
**所以建议大家做题的时候,一定要想清楚逻辑,每一步做什么。把题目所有情况想到位,相应的代码写出来之后,再去追求简洁代码的效果。**
-## 迭代法
+### 迭代法
这道题目我们也可以使用迭代法,但要注意,这里的迭代法可不是前中后序的迭代写法,因为本题的本质是判断两个树是否是相互翻转的,其实已经不是所谓二叉树遍历的前中后序的关系了。
这里我们可以使用队列来比较两个树(根节点的左右子树)是否相互翻转,(**注意这不是层序遍历**)
-### 使用队列
+#### 使用队列
通过队列来判断根节点的左子树和右子树的内侧和外侧是否相等,如动画所示:
@@ -207,7 +209,7 @@ public:
};
```
-### 使用栈
+#### 使用栈
细心的话,其实可以发现,这个迭代法,其实是把左右两个子树要比较的元素顺序放进一个容器,然后成对成对的取出来进行比较,那么其实使用栈也是可以的。
@@ -254,12 +256,12 @@ public:
这两道题目基本和本题是一样的,只要稍加修改就可以AC。
-* 100.相同的树
-* 572.另一个树的子树
+* [100.相同的树](https://leetcode.cn/problems/same-tree/)
+* [572.另一个树的子树](https://leetcode.cn/problems/subtree-of-another-tree/)
-# 其他语言版本
+## 其他语言版本
-Java
+### Java:
```Java
/**
@@ -364,7 +366,7 @@ Java
```
-Python
+### Python:
递归法:
```python
@@ -470,7 +472,8 @@ class Solution:
return True
```
-Go
+### Go:
+
```go
/**
* Definition for a binary tree node.
@@ -521,8 +524,7 @@ func isSymmetric(root *TreeNode) bool {
}
```
-
-JavaScript
+### JavaScript:
递归判断是否为对称二叉树:
```javascript
@@ -610,7 +612,7 @@ var isSymmetric = function(root) {
};
```
-TypeScript:
+### TypeScript:
> 递归法
@@ -679,7 +681,7 @@ function isSymmetric(root: TreeNode | null): boolean {
};
```
-Swift:
+### Swift:
> 递归
```swift
@@ -761,7 +763,7 @@ func isSymmetric3(_ root: TreeNode?) -> Bool {
}
```
-Scala
+### Scala:
> 递归:
```scala
@@ -835,7 +837,7 @@ object Solution {
}
```
-## Rust
+### Rust:
递归:
```rust
@@ -900,3 +902,4 @@ impl Solution {
+
diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md
index c2ad9508..ce9a247c 100644
--- a/problems/0102.二叉树的层序遍历.md
+++ b/problems/0102.二叉树的层序遍历.md
@@ -8,21 +8,23 @@
# 二叉树层序遍历登场!
-《代码随想录》算法视频公开课:[讲透二叉树的层序遍历 | 广度优先搜索 | LeetCode:102.二叉树的层序遍历](https://www.bilibili.com/video/BV1GY4y1u7b2),相信结合视频在看本篇题解,更有助于大家对本题的理解。
+## 算法公开课
+
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[讲透二叉树的层序遍历 | 广度优先搜索 | LeetCode:102.二叉树的层序遍历](https://www.bilibili.com/video/BV1GY4y1u7b2),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
学会二叉树的层序遍历,可以一口气打完以下十题:
-* 102.二叉树的层序遍历
-* 107.二叉树的层次遍历II
-* 199.二叉树的右视图
-* 637.二叉树的层平均值
-* 429.N叉树的层序遍历
-* 515.在每个树行中找最大值
-* 116.填充每个节点的下一个右侧节点指针
-* 117.填充每个节点的下一个右侧节点指针II
-* 104.二叉树的最大深度
-* 111.二叉树的最小深度
+* [102.二叉树的层序遍历](https://leetcode.cn/problems/binary-tree-level-order-traversal/)
+* [107.二叉树的层次遍历II](https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/)
+* [199.二叉树的右视图](https://leetcode.cn/problems/binary-tree-right-side-view/)
+* [637.二叉树的层平均值](https://leetcode.cn/problems/binary-tree-right-side-view/)
+* [429.N叉树的层序遍历](https://leetcode.cn/problems/n-ary-tree-level-order-traversal/)
+* [515.在每个树行中找最大值](https://leetcode.cn/problems/find-largest-value-in-each-tree-row/)
+* [116.填充每个节点的下一个右侧节点指针](https://leetcode.cn/problems/populating-next-right-pointers-in-each-node/)
+* [117.填充每个节点的下一个右侧节点指针II](https://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii/)
+* [104.二叉树的最大深度](https://leetcode.cn/problems/maximum-depth-of-binary-tree/)
+* [111.二叉树的最小深度](https://leetcode.cn/problems/minimum-depth-of-binary-tree/)
@@ -31,7 +33,7 @@
-# 102.二叉树的层序遍历
+## 102.二叉树的层序遍历
[力扣题目链接](https://leetcode.cn/problems/binary-tree-level-order-traversal/)
@@ -39,7 +41,7 @@

-思路:
+### 思路
我们之前讲过了三篇关于二叉树的深度优先遍历的文章:
@@ -63,7 +65,7 @@
代码如下:**这份代码也可以作为二叉树层序遍历的模板,打十个就靠它了**。
-C++代码:
+c++代码如下:
```CPP
class Solution {
@@ -111,7 +113,9 @@ public:
};
```
-java:
+### 其他语言版本
+
+#### Java:
```Java
// 102.二叉树的层序遍历
@@ -167,7 +171,7 @@ class Solution {
}
```
-python3代码:
+#### Python:
```python
@@ -219,12 +223,9 @@ class Solution:
self.helper(node.left, level + 1, levels)
self.helper(node.right, level + 1, levels)
-
```
-
-
-go:
+#### Go:
```go
/**
@@ -320,7 +321,7 @@ func levelOrder(root *TreeNode) (res [][]int) {
}
```
-javascript代码:
+#### Javascript:
```javascript
var levelOrder = function(root) {
@@ -350,7 +351,7 @@ var levelOrder = function(root) {
```
-TypeScript:
+#### TypeScript:
```typescript
function levelOrder(root: TreeNode | null): number[][] {
@@ -377,7 +378,7 @@ function levelOrder(root: TreeNode | null): number[][] {
};
```
-Swift:
+#### Swift:
```swift
func levelOrder(_ root: TreeNode?) -> [[Int]] {
@@ -403,7 +404,7 @@ func levelOrder(_ root: TreeNode?) -> [[Int]] {
}
```
-Scala:
+#### Scala:
```scala
// 102.二叉树的层序遍历
@@ -430,7 +431,7 @@ object Solution {
}
```
-Rust:
+#### Rust:
```rust
use std::cell::RefCell;
@@ -466,7 +467,7 @@ impl Solution {
**此时我们就掌握了二叉树的层序遍历了,那么如下九道力扣上的题目,只需要修改模板的两三行代码(不能再多了),便可打倒!**
-# 107.二叉树的层次遍历 II
+## 107.二叉树的层次遍历 II
[力扣题目链接](https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/)
@@ -474,7 +475,7 @@ impl Solution {

-思路:
+### 思路
相对于102.二叉树的层序遍历,就是最后把result数组反转一下就可以了。
@@ -506,7 +507,9 @@ public:
};
```
-python代码:
+### 其他语言版本
+
+#### Python:
```python
class Solution:
@@ -537,7 +540,7 @@ class Solution:
return result[::-1]
```
-Java:
+#### Java:
```java
// 107. 二叉树的层序遍历 II
@@ -618,12 +621,10 @@ class Solution {
return ans;
}
-}
+
```
-
-
-go:
+#### Go:
```GO
/**
@@ -662,7 +663,7 @@ func levelOrderBottom(root *TreeNode) [][]int {
}
```
-javascript代码
+#### Javascript:
```javascript
var levelOrderBottom = function(root) {
@@ -688,7 +689,7 @@ var levelOrderBottom = function(root) {
};
```
-TypeScript:
+#### TypeScript:
```typescript
function levelOrderBottom(root: TreeNode | null): number[][] {
@@ -711,7 +712,7 @@ function levelOrderBottom(root: TreeNode | null): number[][] {
};
```
-Swift:
+#### Swift:
```swift
func levelOrderBottom(_ root: TreeNode?) -> [[Int]] {
@@ -737,8 +738,7 @@ func levelOrderBottom(_ root: TreeNode?) -> [[Int]] {
}
```
-
-Scala:
+#### Scala:
```scala
// 107.二叉树的层次遍历II
@@ -764,7 +764,10 @@ object Solution {
res.reverse.toList
}
-Rust:
+
+```
+
+#### Rust:
```rust
use std::cell::RefCell;
@@ -796,7 +799,7 @@ impl Solution {
}
```
-# 199.二叉树的右视图
+## 199.二叉树的右视图
[力扣题目链接](https://leetcode.cn/problems/binary-tree-right-side-view/)
@@ -804,7 +807,7 @@ impl Solution {

-思路:
+### 思路
层序遍历的时候,判断是否遍历到单层的最后面的元素,如果是,就放进result数组中,随后返回result就可以了。
@@ -832,7 +835,9 @@ public:
};
```
-python代码:
+### 其他语言版本
+
+#### Python:
```python
# Definition for a binary tree node.
@@ -866,8 +871,7 @@ class Solution:
return right_view
```
-
-Java:
+#### Java:
```java
// 199.二叉树的右视图
@@ -911,7 +915,7 @@ public class N0199 {
}
```
-go:
+#### Go:
```GO
/**
@@ -945,8 +949,7 @@ func rightSideView(root *TreeNode) []int {
}
```
-
-javascript代码:
+#### Javascript:
```javascript
var rightSideView = function(root) {
@@ -972,7 +975,7 @@ var rightSideView = function(root) {
};
```
-TypeScript:
+#### TypeScript:
```typescript
function rightSideView(root: TreeNode | null): number[] {
@@ -992,7 +995,7 @@ function rightSideView(root: TreeNode | null): number[] {
};
```
-Swift:
+#### Swift:
```swift
func rightSideView(_ root: TreeNode?) -> [Int] {
@@ -1017,7 +1020,7 @@ func rightSideView(_ root: TreeNode?) -> [Int] {
}
```
-Scala:
+#### Scala:
```scala
// 199.二叉树的右视图
@@ -1043,7 +1046,7 @@ object Solution {
}
```
-rust:
+#### Rust:
```rust
use std::cell::RefCell;
@@ -1076,7 +1079,7 @@ impl Solution {
}
```
-# 637.二叉树的层平均值
+## 637.二叉树的层平均值
[力扣题目链接](https://leetcode.cn/problems/average-of-levels-in-binary-tree/)
@@ -1084,7 +1087,7 @@ impl Solution {

-思路:
+### 思路
本题就是层序遍历的时候把一层求个总和在取一个均值。
@@ -1115,7 +1118,9 @@ public:
```
-python代码:
+### 其他语言版本
+
+#### Python:
```python
class Solution:
@@ -1155,7 +1160,7 @@ class Solution:
return averages
```
-java:
+#### Java:
```java
// 637. 二叉树的层平均值
@@ -1197,7 +1202,7 @@ public class N0637 {
}
```
-go:
+#### Go:
```GO
/**
@@ -1235,7 +1240,7 @@ func averageOfLevels(root *TreeNode) []float64 {
}
```
-javascript代码:
+#### Javascript:
```javascript
var averageOfLevels = function(root) {
@@ -1262,7 +1267,7 @@ var averageOfLevels = function(root) {
};
```
-TypeScript:
+#### TypeScript:
```typescript
function averageOfLevels(root: TreeNode | null): number[] {
@@ -1286,7 +1291,7 @@ function averageOfLevels(root: TreeNode | null): number[] {
};
```
-Swift:
+#### Swift:
```swift
func averageOfLevels(_ root: TreeNode?) -> [Double] {
@@ -1313,7 +1318,7 @@ func averageOfLevels(_ root: TreeNode?) -> [Double] {
}
```
-Scala:
+#### Scala:
```scala
// 637.二叉树的层平均值
@@ -1339,7 +1344,7 @@ object Solution {
}
```
-rust:
+#### Rust:
```rust
use std::cell::RefCell;
@@ -1372,7 +1377,7 @@ impl Solution {
}
```
-# 429.N叉树的层序遍历
+## 429.N叉树的层序遍历
[力扣题目链接](https://leetcode.cn/problems/n-ary-tree-level-order-traversal/)
@@ -1390,8 +1395,7 @@ impl Solution {
[5,6]
]
-
-思路:
+### 思路
这道题依旧是模板题,只不过一个节点有多个孩子了
@@ -1423,7 +1427,9 @@ public:
};
```
-python代码:
+### 其他语言版本
+
+#### Python:
```python
"""
@@ -1475,7 +1481,7 @@ class Solution:
return result
```
-java:
+#### Java:
```java
// 429. N 叉树的层序遍历
@@ -1535,8 +1541,7 @@ public class N0429 {
}
```
-
-go:
+#### Go:
```GO
/**
@@ -1567,7 +1572,7 @@ func levelOrder(root *Node) [][]int {
}
```
-JavaScript代码:
+#### JavaScript:
```JavaScript
var levelOrder = function(root) {
@@ -1596,7 +1601,7 @@ var levelOrder = function(root) {
};
```
-TypeScript:
+#### TypeScript:
```typescript
function levelOrder(root: Node | null): number[][] {
@@ -1618,7 +1623,7 @@ function levelOrder(root: Node | null): number[][] {
};
```
-Swift:
+#### Swift:
```swift
func levelOrder(_ root: Node?) -> [[Int]] {
@@ -1643,7 +1648,7 @@ func levelOrder(_ root: Node?) -> [[Int]] {
}
```
-Scala:
+#### Scala:
```scala
// 429.N叉树的层序遍历
@@ -1672,7 +1677,7 @@ object Solution {
}
```
-rust:
+#### Rust:
```rust
pub struct Solution;
@@ -1720,7 +1725,7 @@ impl Solution {
}
```
-# 515.在每个树行中找最大值
+## 515.在每个树行中找最大值
[力扣题目链接](https://leetcode.cn/problems/find-largest-value-in-each-tree-row/)
@@ -1728,7 +1733,7 @@ impl Solution {

-思路:
+### 思路
层序遍历,取每一层的最大值
@@ -1758,7 +1763,9 @@ public:
};
```
-python代码:
+### 其他语言版本
+
+#### Python:
```python
# Definition for a binary tree node.
@@ -1794,7 +1801,7 @@ class Solution:
return result
```
-java代码:
+#### Java:
```java
class Solution {
@@ -1820,7 +1827,7 @@ class Solution {
}
```
-go:
+#### Go:
```GO
/**
@@ -1864,7 +1871,7 @@ func max(x, y int) int {
}
```
-javascript代码:
+#### Javascript:
```javascript
var largestValues = function(root) {
@@ -1890,7 +1897,7 @@ var largestValues = function(root) {
};
```
-TypeScript:
+#### TypeScript:
```typescript
function largestValues(root: TreeNode | null): number[] {
@@ -1916,7 +1923,7 @@ function largestValues(root: TreeNode | null): number[] {
};
```
-Swift:
+#### Swift:
```swift
func largestValues(_ root: TreeNode?) -> [Int] {
@@ -1943,7 +1950,7 @@ func largestValues(_ root: TreeNode?) -> [Int] {
}
```
-Scala:
+#### Scala:
```scala
// 515.在每个树行中找最大值
@@ -1970,7 +1977,7 @@ object Solution {
}
```
-rust:
+#### Rust:
```rust
use std::cell::RefCell;
@@ -2002,7 +2009,7 @@ impl Solution {
}
```
-# 116.填充每个节点的下一个右侧节点指针
+## 116.填充每个节点的下一个右侧节点指针
[力扣题目链接](https://leetcode.cn/problems/populating-next-right-pointers-in-each-node/)
@@ -2024,7 +2031,7 @@ struct Node {

-思路:
+### 思路
本题依然是层序遍历,只不过在单层遍历的时候记录一下本层的头部节点,然后在遍历的时候让前一个节点指向本节点就可以了
@@ -2063,7 +2070,9 @@ public:
};
```
-java代码:
+### 其他语言版本
+
+#### Java:
```java
class Solution {
@@ -2093,7 +2102,7 @@ class Solution {
}
```
-python代码:
+#### Python:
```python
"""
@@ -2133,7 +2142,7 @@ class Solution:
return root
```
-go:
+#### Go:
```GO
/**
@@ -2173,7 +2182,7 @@ func connect(root *Node) *Node {
```
-JavaScript:
+#### JavaScript:
```javascript
/**
@@ -2209,7 +2218,7 @@ var connect = function(root) {
```
-TypeScript:
+#### TypeScript:
```typescript
function connect(root: Node | null): Node | null {
@@ -2234,7 +2243,7 @@ function connect(root: Node | null): Node | null {
};
```
-Swift:
+#### Swift:
```swift
func connect(_ root: Node?) -> Node? {
@@ -2266,7 +2275,7 @@ func connect(_ root: Node?) -> Node? {
}
```
-Scala:
+#### Scala:
```scala
// 116.填充每个节点的下一个右侧节点指针
@@ -2297,11 +2306,11 @@ object Solution {
}
```
-# 117.填充每个节点的下一个右侧节点指针II
+## 117.填充每个节点的下一个右侧节点指针II
[力扣题目链接](https://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii/)
-思路:
+### 思路
这道题目说是二叉树,但116题目说是完整二叉树,其实没有任何差别,一样的代码一样的逻辑一样的味道
@@ -2339,7 +2348,9 @@ public:
};
```
-Java 代码:
+### 其他语言版本
+
+#### Java:
```java
// 二叉树之层次遍历
@@ -2377,7 +2388,7 @@ class Solution {
}
```
-python代码:
+#### Python:
```python
# 层序遍历解法
@@ -2420,7 +2431,7 @@ class Solution:
```
-go:
+#### Go:
```GO
/**
@@ -2459,7 +2470,7 @@ func connect(root *Node) *Node {
}
```
-JavaScript:
+#### JavaScript:
```javascript
/**
@@ -2494,7 +2505,7 @@ var connect = function(root) {
};
```
-TypeScript:
+#### TypeScript:
```typescript
function connect(root: Node | null): Node | null {
@@ -2519,7 +2530,7 @@ function connect(root: Node | null): Node | null {
};
```
-Swift:
+#### Swift:
```swift
func connect(_ root: Node?) -> Node? {
@@ -2551,7 +2562,7 @@ func connect(_ root: Node?) -> Node? {
}
```
-Scala:
+#### Scala:
```scala
// 117.填充每个节点的下一个右侧节点指针II
@@ -2582,7 +2593,7 @@ object Solution {
}
```
-# 104.二叉树的最大深度
+## 104.二叉树的最大深度
[力扣题目链接](https://leetcode.cn/problems/maximum-depth-of-binary-tree/)
@@ -2600,7 +2611,7 @@ object Solution {
返回它的最大深度 3 。
-思路:
+### 思路
使用迭代法的话,使用层序遍历是最为合适的,因为最大的深度就是二叉树的层数,和层序遍历的方式极其吻合。
@@ -2635,7 +2646,9 @@ public:
};
```
-Java:
+### 其他语言版本
+
+#### Java:
```Java
class Solution {
@@ -2661,7 +2674,7 @@ class Solution {
}
```
-Python:
+#### Python:
```python 3
# Definition for a binary tree node.
@@ -2691,7 +2704,7 @@ class Solution:
```
-Go:
+#### Go:
```go
/**
@@ -2726,7 +2739,7 @@ func maxDepth(root *TreeNode) int {
}
```
-JavaScript:
+#### JavaScript:
```javascript
/**
@@ -2759,7 +2772,7 @@ var maxDepth = function(root) {
};
```
-TypeScript:
+#### TypeScript:
```typescript
function maxDepth(root: TreeNode | null): number {
@@ -2779,7 +2792,7 @@ function maxDepth(root: TreeNode | null): number {
};
```
-Swift:
+#### Swift:
```swift
func maxDepth(_ root: TreeNode?) -> Int {
@@ -2804,7 +2817,7 @@ func maxDepth(_ root: TreeNode?) -> Int {
}
```
-Scala:
+#### Scala:
```scala
// 104.二叉树的最大深度
@@ -2829,7 +2842,7 @@ object Solution {
}
```
-rust:
+#### Rust:
```rust
use std::cell::RefCell;
@@ -2859,10 +2872,12 @@ impl Solution {
}
```
-# 111.二叉树的最小深度
+## 111.二叉树的最小深度
[力扣题目链接](https://leetcode.cn/problems/minimum-depth-of-binary-tree/)
+### 思路
+
相对于 104.二叉树的最大深度 ,本题还也可以使用层序遍历的方式来解决,思路是一样的。
**需要注意的是,只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点**
@@ -2895,7 +2910,9 @@ public:
};
```
-Java:
+### 其他语言版本
+
+#### Java:
```java
class Solution {
@@ -2925,9 +2942,7 @@ class Solution {
}
```
-
-
-Python 3:
+#### Python:
```python 3
# Definition for a binary tree node.
@@ -2960,7 +2975,7 @@ class Solution:
return depth
```
-Go:
+#### Go:
```go
/**
@@ -2999,7 +3014,7 @@ func minDepth(root *TreeNode) int {
}
```
-JavaScript:
+#### JavaScript:
```javascript
/**
@@ -3035,7 +3050,7 @@ var minDepth = function(root) {
};
```
-TypeScript:
+#### TypeScript:
```typescript
function minDepth(root: TreeNode | null): number {
@@ -3056,7 +3071,7 @@ function minDepth(root: TreeNode | null): number {
};
```
-Swift:
+#### Swift:
```swift
func minDepth(_ root: TreeNode?) -> Int {
@@ -3082,7 +3097,7 @@ func minDepth(_ root: TreeNode?) -> Int {
}
```
-Scala:
+#### Scala:
```scala
// 111.二叉树的最小深度
@@ -3108,7 +3123,7 @@ object Solution {
}
```
-rust:
+#### Rust:
```rust
use std::cell::RefCell;
@@ -3141,28 +3156,27 @@ impl Solution {
}
```
-# 总结
+## 总结
二叉树的层序遍历,**就是图论中的广度优先搜索在二叉树中的应用**,需要借助队列来实现(此时又发现队列的一个应用了)。
来吧,一口气打十个:
-* 102.二叉树的层序遍历
-* 107.二叉树的层次遍历II
-* 199.二叉树的右视图
-* 637.二叉树的层平均值
-* 429.N叉树的层序遍历
-* 515.在每个树行中找最大值
-* 116.填充每个节点的下一个右侧节点指针
-* 117.填充每个节点的下一个右侧节点指针II
-* 104.二叉树的最大深度
-* 111.二叉树的最小深度
+* [102.二叉树的层序遍历](https://leetcode.cn/problems/binary-tree-level-order-traversal/)
+* [107.二叉树的层次遍历II](https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/)
+* [199.二叉树的右视图](https://leetcode.cn/problems/binary-tree-right-side-view/)
+* [637.二叉树的层平均值](https://leetcode.cn/problems/binary-tree-right-side-view/)
+* [429.N叉树的层序遍历](https://leetcode.cn/problems/n-ary-tree-level-order-traversal/)
+* [515.在每个树行中找最大值](https://leetcode.cn/problems/find-largest-value-in-each-tree-row/)
+* [116.填充每个节点的下一个右侧节点指针](https://leetcode.cn/problems/populating-next-right-pointers-in-each-node/)
+* [117.填充每个节点的下一个右侧节点指针II](https://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii/)
+* [104.二叉树的最大深度](https://leetcode.cn/problems/maximum-depth-of-binary-tree/)
+* [111.二叉树的最小深度](https://leetcode.cn/problems/minimum-depth-of-binary-tree/)
**致敬叶师傅!**
-
-
+
diff --git a/problems/0104.二叉树的最大深度.md b/problems/0104.二叉树的最大深度.md
index 7130867b..05044375 100644
--- a/problems/0104.二叉树的最大深度.md
+++ b/problems/0104.二叉树的最大深度.md
@@ -5,6 +5,7 @@
参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!
+ # 104.二叉树的最大深度 [力扣题目链接](https://leetcode.cn/problems/maximum-depth-of-binary-tree/) @@ -23,17 +24,19 @@ 返回它的最大深度 3 。 -# 思路 +## 算法公开课 + +**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[二叉树的高度和深度有啥区别?究竟用什么遍历顺序?很多录友搞不懂 | 104.二叉树的最大深度](https://www.bilibili.com/video/BV1Gd4y1V75u),相信结合视频再看本篇题解,更有助于大家对本题的理解**。 + +## 思路 看完本篇可以一起做了如下两道题目: -* 104.二叉树的最大深度 -* 559.n叉树的最大深度 - -《代码随想录》算法视频公开课:[二叉树的高度和深度有啥区别?究竟用什么遍历顺序?很多录友搞不懂 | 104.二叉树的最大深度](https://www.bilibili.com/video/BV1Gd4y1V75u),相信结合视频在看本篇题解,更有助于大家对本题的理解。 +* [104.二叉树的最大深度](https://leetcode.cn/problems/maximum-depth-of-binary-tree/) +* [559.n叉树的最大深度](https://leetcode.cn/problems/maximum-depth-of-n-ary-tree/) -## 递归法 +### 递归法 本题可以使用前序(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的是高度。 @@ -164,7 +167,7 @@ public: }; ``` -## 迭代法 +### 迭代法 使用迭代法的话,使用层序遍历是最为合适的,因为最大的深度就是二叉树的层数,和层序遍历的方式极其吻合。 @@ -202,10 +205,11 @@ public: }; ``` - 那么我们可以顺便解决一下n叉树的最大深度问题 -# 559.n叉树的最大深度 +## 相关题目推荐 + +### 559.n叉树的最大深度 [力扣题目链接](https://leetcode.cn/problems/maximum-depth-of-n-ary-tree/) @@ -219,11 +223,11 @@ public: 我们应返回其最大深度,3。 -思路: +### 思路 依然可以提供递归法和迭代法,来解决这个问题,思路是和二叉树思路一样的,直接给出代码如下: -## 递归法 +#### 递归法 c++代码: @@ -240,7 +244,7 @@ public: } }; ``` -## 迭代法 +#### 迭代法 依然是层序遍历,代码如下: @@ -267,11 +271,11 @@ public: }; ``` -# 其他语言版本 +## 其他语言版本 -## java +### Java: -### 104.二叉树的最大深度 +104.二叉树的最大深度 ```java class solution { @@ -344,7 +348,8 @@ class solution { } ``` -### 559.n叉树的最大深度 +559.n叉树的最大深度 + ```java class Solution { /*递归法,后序遍历求root节点的高度*/ @@ -391,9 +396,9 @@ class solution { } ``` -## python +### Python : -### 104.二叉树的最大深度 +104.二叉树的最大深度 递归法: ```python @@ -448,7 +453,7 @@ class Solution: ``` -### 559.n叉树的最大深度 +559.n叉树的最大深度 递归法: ```python @@ -522,9 +527,10 @@ class Solution: return max_depth ``` +### Go: + +104.二叉树的最大深度 -## go -### 104.二叉树的最大深度 ```go /** * definition for a binary tree node. @@ -574,7 +580,7 @@ func maxdepth(root *treenode) int { ``` -### 559. n叉树的最大深度 +559. n叉树的最大深度 ```go func maxDepth(root *Node) int { @@ -598,9 +604,9 @@ func maxDepth(root *Node) int { } ``` -## javascript +### Javascript : -### 104.二叉树的最大深度 +104.二叉树的最大深度 ```javascript var maxdepth = function(root) { @@ -649,7 +655,7 @@ var maxDepth = function(root) { }; ``` -### 559.n叉树的最大深度 +559.n叉树的最大深度 N叉树的最大深度 递归写法 ```js @@ -683,9 +689,9 @@ var maxDepth = function(root) { }; ``` -## TypeScript +### TypeScript: -### 104.二叉树的最大深度 +104.二叉树的最大深度 ```typescript // 后续遍历(自下而上) @@ -728,7 +734,7 @@ function maxDepth(root: TreeNode | null): number { }; ``` -### 559.n叉树的最大深度 +559.n叉树的最大深度 ```typescript // 后续遍历(自下而上) @@ -756,9 +762,9 @@ function maxDepth(root: TreeNode | null): number { ``` -## C +### C: -### 104.二叉树的最大深度 +104.二叉树的最大深度 二叉树最大深度递归 ```c @@ -814,9 +820,9 @@ int maxDepth(struct TreeNode* root){ } ``` -## Swift +### Swift: -### 104.二叉树的最大深度 +104.二叉树的最大深度 ```swift // 递归 - 后序 @@ -856,7 +862,7 @@ func maxDepth(_ root: TreeNode?) -> Int { } ``` -### 559.n叉树的最大深度 +559.n叉树的最大深度 ```swift // 递归 @@ -893,9 +899,10 @@ func maxDepth1(_ root: Node?) -> Int { } ``` -## Scala +### Scala: + +104.二叉树的最大深度 -### 104.二叉树的最大深度 递归法: ```scala object Solution { @@ -934,7 +941,7 @@ object Solution { } ``` -### 559.n叉树的最大深度 +559.n叉树的最大深度 递归法: ```scala @@ -972,8 +979,8 @@ object Solution { } ``` -## rust -### 0104.二叉树的最大深度 +### Rust: +0104.二叉树的最大深度 递归: ```rust diff --git a/problems/0106.从中序与后序遍历序列构造二叉树.md b/problems/0106.从中序与后序遍历序列构造二叉树.md index a0bab999..0144fc5c 100644 --- a/problems/0106.从中序与后序遍历序列构造二叉树.md +++ b/problems/0106.从中序与后序遍历序列构造二叉树.md @@ -29,9 +29,9 @@  -# 视频讲解 +## 算法公开课 -**《代码随想录》算法视频公开课:[坑很多!来看看你掉过几次坑 | LeetCode:106.从中序与后序遍历序列构造二叉树](https://www.bilibili.com/video/BV1vW4y1i7dn),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 +**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[坑很多!来看看你掉过几次坑 | LeetCode:106.从中序与后序遍历序列构造二叉树](https://www.bilibili.com/video/BV1vW4y1i7dn),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 ## 思路 @@ -158,8 +158,6 @@ root->right = traversal(rightInorder, rightPostorder); 完整代码如下: -### C++完整代码 - ```CPP class Solution { private: @@ -281,8 +279,6 @@ public: 下面给出用下标索引写出的代码版本:(思路是一样的,只不过不用重复定义vector了,每次用下标索引来分割) -### C++优化版本 - ```CPP class Solution { private: @@ -400,8 +396,9 @@ public: }; ``` +## 相关题目推荐 -# 105.从前序与中序遍历序列构造二叉树 +### 105.从前序与中序遍历序列构造二叉树 [力扣题目链接](https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) @@ -418,7 +415,7 @@ public:  -## 思路 +### 思路 本题和106是一样的道理。 @@ -547,7 +544,7 @@ public: }; ``` -# 思考题 +## 思考题 前序和中序可以唯一确定一棵二叉树。 @@ -569,7 +566,7 @@ tree2 的前序遍历是[1 2 3], 后序遍历是[3 2 1]。 所以前序和后序不能唯一确定一棵二叉树! -# 总结 +## 总结 之前我们讲的二叉树题目都是各种遍历二叉树,这次开始构造二叉树了,思路其实比较简单,但是真正代码实现出来并不容易。 @@ -585,9 +582,9 @@ tree2 的前序遍历是[1 2 3], 后序遍历是[3 2 1]。 -# 其他语言版本 +## 其他语言版本 -## Java +### Java 106.从中序与后序遍历序列构造二叉树 @@ -688,7 +685,7 @@ class Solution { } ``` -## Python +### Python 105.从前序与中序遍历序列构造二叉树 @@ -754,7 +751,7 @@ class Solution: return root ``` -## Go +### Go 106 从中序与后序遍历序列构造二叉树 @@ -833,9 +830,7 @@ func build(pre []int, in []int, root int, l, r int) *TreeNode { ``` - - -## JavaScript +### JavaScript ```javascript var buildTree = function(inorder, postorder) { @@ -863,7 +858,7 @@ var buildTree = function(preorder, inorder) { }; ``` -## TypeScript +### TypeScript > 106.从中序与后序遍历序列构造二叉树 @@ -969,7 +964,7 @@ function buildTree(preorder: number[], inorder: number[]): TreeNode | null { }; ``` -## C +### C 106 从中序与后序遍历序列构造二叉树 @@ -1047,7 +1042,7 @@ struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int in } ``` -## Swift +### Swift 105 从前序与中序遍历序列构造二叉树 @@ -1140,7 +1135,7 @@ class Solution_0106 { } ``` -## Scala +### Scala 106 从中序与后序遍历序列构造二叉树 @@ -1188,7 +1183,7 @@ object Solution { } ``` -## rust +### Rust 106 从中序与后序遍历序列构造二叉树 @@ -1238,3 +1233,4 @@ impl Solution {
+
diff --git a/problems/0108.将有序数组转换为二叉搜索树.md b/problems/0108.将有序数组转换为二叉搜索树.md
index 056ef3e2..e699005e 100644
--- a/problems/0108.将有序数组转换为二叉搜索树.md
+++ b/problems/0108.将有序数组转换为二叉搜索树.md
@@ -20,11 +20,11 @@

-# 算法公开课
+## 算法公开课
-**《代码随想录》算法视频公开课:[构造平衡二叉搜索树!| LeetCode:108.将有序数组转换为二叉搜索树](https://www.bilibili.com/video/BV1uR4y1X7qL?share_source=copy_web),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[构造平衡二叉搜索树!| LeetCode:108.将有序数组转换为二叉搜索树](https://www.bilibili.com/video/BV1uR4y1X7qL?share_source=copy_web),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
-# 思路
+## 思路
做这道题目之前大家可以了解一下这几道:
@@ -71,7 +71,7 @@
**这也是题目中强调答案不是唯一的原因。 理解这一点,这道题目算是理解到位了**。
-## 递归
+### 递归
递归三部曲:
@@ -155,7 +155,7 @@ public:
**注意:在调用traversal的时候传入的left和right为什么是0和nums.size() - 1,因为定义的区间为左闭右闭**。
-## 迭代法
+### 迭代法
迭代法可以通过三个队列来模拟,一个队列放遍历的节点,一个队列放左区间下标,一个队列放右区间下标。
@@ -203,7 +203,7 @@ public:
};
```
-# 总结
+## 总结
**在[二叉树:构造二叉树登场!](https://programmercarl.com/0106.从中序与后序遍历序列构造二叉树.html) 和 [二叉树:构造一棵最大的二叉树](https://programmercarl.com/0654.最大二叉树.html)之后,我们顺理成章的应该构造一下二叉搜索树了,一不小心还是一棵平衡二叉搜索树**。
@@ -216,10 +216,10 @@ public:
最后依然给出迭代的方法,其实就是模拟取中间元素,然后不断分割去构造二叉树的过程。
-# 其他语言版本
+## 其他语言版本
-## Java
+### Java
递归: 左闭右开 [left,right)
```Java
@@ -315,7 +315,7 @@ class Solution {
}
```
-## Python
+### Python
递归法
```python
class Solution:
@@ -377,7 +377,7 @@ class Solution:
```
-## Go
+### Go
递归(隐含回溯)
@@ -396,7 +396,7 @@ func sortedArrayToBST(nums []int) *TreeNode {
}
```
-## JavaScript
+### JavaScript
递归
```javascript
@@ -453,7 +453,7 @@ var sortedArrayToBST = function(nums) {
return root;
};
```
-## TypeScript
+### TypeScript
```typescript
function sortedArrayToBST(nums: number[]): TreeNode | null {
@@ -469,7 +469,7 @@ function sortedArrayToBST(nums: number[]): TreeNode | null {
};
```
-## C
+### C
递归
```c
@@ -490,7 +490,7 @@ struct TreeNode* sortedArrayToBST(int* nums, int numsSize) {
}
```
-## Scala
+### Scala
递归:
@@ -511,7 +511,7 @@ object Solution {
}
```
-## rust
+### Rust
递归:
@@ -536,3 +536,4 @@ impl Solution {
+
diff --git a/problems/0110.平衡二叉树.md b/problems/0110.平衡二叉树.md
index e10a612a..c7df9c8f 100644
--- a/problems/0110.平衡二叉树.md
+++ b/problems/0110.平衡二叉树.md
@@ -33,8 +33,9 @@
返回 false 。
+## 算法公开课
-**《代码随想录》算法视频公开课:[后序遍历求高度,高度判断是否平衡 | LeetCode:110.平衡二叉树](https://www.bilibili.com/video/BV1Ug411S7my),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[后序遍历求高度,高度判断是否平衡 | LeetCode:110.平衡二叉树](https://www.bilibili.com/video/BV1Ug411S7my),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
## 题外话
@@ -357,7 +358,7 @@ public:
## 其他语言版本
-### Java
+### Java:
```Java
class Solution {
@@ -498,7 +499,7 @@ class Solution {
}
```
-### Python
+### Python:
递归法:
@@ -620,7 +621,7 @@ class Solution:
height_map[real_node] = 1 + max(left, right)
return True
```
-### Go
+### Go:
```Go
func isBalanced(root *TreeNode) bool {
@@ -652,7 +653,7 @@ func max(a, b int) int {
}
```
-### JavaScript
+### JavaScript:
递归法:
@@ -723,7 +724,7 @@ var isBalanced = function (root) {
};
```
-### TypeScript
+### TypeScript:
```typescript
// 递归法
@@ -741,7 +742,7 @@ function isBalanced(root: TreeNode | null): boolean {
};
```
-### C
+### C:
递归法:
@@ -876,7 +877,7 @@ func getHeight(_ root: TreeNode?) -> Int {
}
```
-### rust
+### Rust:
递归
@@ -912,3 +913,4 @@ impl Solution {
+
diff --git a/problems/0111.二叉树的最小深度.md b/problems/0111.二叉树的最小深度.md
index a1fc8a93..61f9beb7 100644
--- a/problems/0111.二叉树的最小深度.md
+++ b/problems/0111.二叉树的最小深度.md
@@ -26,9 +26,11 @@
返回它的最小深度 2.
-# 思路
+## 算法公开课
-《代码随想录》算法视频公开课:[看起来好像做过,一写就错! | LeetCode:111.二叉树的最小深度](https://www.bilibili.com/video/BV1QD4y1B7e2),相信结合视频在看本篇题解,更有助于大家对本题的理解。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[看起来好像做过,一写就错! | LeetCode:111.二叉树的最小深度](https://www.bilibili.com/video/BV1QD4y1B7e2),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
+
+## 思路
看完了这篇[104.二叉树的最大深度](https://programmercarl.com/0104.二叉树的最大深度.html),再来看看如何求最小深度。
@@ -52,7 +54,7 @@
什么是叶子节点,左右孩子都为空的节点才是叶子节点!
-## 递归法
+### 递归法
来来来,一起递归三部曲:
@@ -199,7 +201,7 @@ public:
};
```
-## 迭代法
+### 迭代法
相对于[104.二叉树的最大深度](https://programmercarl.com/0104.二叉树的最大深度.html),本题还可以使用层序遍历的方式来解决,思路是一样的。
@@ -237,10 +239,10 @@ public:
```
-# 其他语言版本
+## 其他语言版本
-## Java
+### Java:
```Java
class Solution {
@@ -300,7 +302,7 @@ class Solution {
}
```
-## Python
+### Python :
递归法(版本一)
@@ -400,9 +402,7 @@ class Solution:
return depth
```
-
-
-## Go
+### Go:
```go
/**
@@ -463,7 +463,7 @@ func minDepth(root *TreeNode) int {
```
-## JavaScript
+### JavaScript:
递归法:
@@ -509,7 +509,7 @@ var minDepth = function(root) {
};
```
-## TypeScript
+### TypeScript:
> 递归法
@@ -547,7 +547,7 @@ function minDepth(root: TreeNode | null): number {
};
```
-## Swift
+### Swift:
> 递归
```Swift
@@ -594,7 +594,7 @@ func minDepth(_ root: TreeNode?) -> Int {
```
-## Scala
+### Scala:
递归法:
```scala
@@ -633,7 +633,8 @@ object Solution {
}
```
-rust:
+### Rust:
+
```rust
impl Solution {
// 递归
diff --git a/problems/0112.路径总和.md b/problems/0112.路径总和.md
index 39285a3b..be03f719 100644
--- a/problems/0112.路径总和.md
+++ b/problems/0112.路径总和.md
@@ -21,9 +21,9 @@
返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。
-## 视频讲解
+## 算法公开课
-**《代码随想录》算法视频公开课:[拿不准的遍历顺序,搞不清的回溯过程,我太难了! | LeetCode:112. 路径总和](https://www.bilibili.com/video/BV19t4y1L7CR),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[拿不准的遍历顺序,搞不清的回溯过程,我太难了! | LeetCode:112. 路径总和](https://www.bilibili.com/video/BV19t4y1L7CR),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
## 思路
@@ -32,8 +32,8 @@
那么接下来我通过详细讲解如下两道题,来回答这个问题:
-* 112.路径总和
-* 113.路径总和ii
+* [112.路径总和](https://leetcode.cn/problems/path-sum/)
+* [113.路径总和ii](https://leetcode.cn/problems/path-sum-ii/)
这道题我们要遍历从根节点到叶子节点的路径看看总和是不是目标和。
@@ -218,7 +218,9 @@ public:
如果大家完全理解了本题的递归方法之后,就可以顺便把leetcode上113. 路径总和ii做了。
-# 113. 路径总和ii
+## 相关题目推荐
+
+### 113. 路径总和ii
[力扣题目链接](https://leetcode.cn/problems/path-sum-ii/)
@@ -232,7 +234,7 @@ public:

-## 思路
+### 思路
113.路径总和ii要遍历整个树,找到所有路径,**所以递归函数不要返回值!**
@@ -289,7 +291,7 @@ public:
至于113. 路径总和ii 的迭代法我并没有写,用迭代方式记录所有路径比较麻烦,也没有必要,如果大家感兴趣的话,可以再深入研究研究。
-## 总结
+### 总结
本篇通过leetcode上112. 路径总和 和 113. 路径总和ii 详细的讲解了 递归函数什么时候需要返回值,什么不需要返回值。
@@ -300,11 +302,11 @@ public:
-# 其他语言版本
+## 其他语言版本
-## java
+### Java
-### 0112.路径总和
+0112.路径总和
```java
class solution {
@@ -422,7 +424,7 @@ class solution {
}
```
-### 0113.路径总和-ii
+0113.路径总和-ii
```java
class solution {
@@ -529,9 +531,9 @@ class Solution {
}
```
-## python
+### Python
-### 0112.路径总和
+0112.路径总和
(版本一) 递归
```python
@@ -618,7 +620,7 @@ class Solution:
-### 0113.路径总和-ii
+0113.路径总和-ii
(版本一) 递归
```python
@@ -719,9 +721,9 @@ class Solution:
```
-## go
+### Go
-### 112. 路径总和
+112. 路径总和
```go
//递归法
@@ -746,7 +748,7 @@ func hasPathSum(root *TreeNode, targetSum int) bool {
}
```
-### 113. 路径总和 II
+113. 路径总和 II
```go
/**
@@ -786,9 +788,9 @@ func traverse(node *TreeNode, result *[][]int, currPath *[]int, targetSum int) {
}
```
-## javascript
+### Javascript
-### 0112.路径总和
+0112.路径总和
**递归**
@@ -852,7 +854,7 @@ let hasPathSum = function(root, targetSum) {
};
```
-### 0113.路径总和-ii
+0113.路径总和-ii
**递归**
@@ -950,9 +952,9 @@ let pathSum = function(root, targetSum) {
};
```
-## TypeScript
+### TypeScript
-### 0112.路径总和
+0112.路径总和
**递归法:**
@@ -1034,7 +1036,7 @@ function hasPathSum(root: TreeNode | null, targetSum: number): boolean {
};
```
-### 0112.路径总和 ii
+0112.路径总和 ii
**递归法:**
@@ -1070,9 +1072,9 @@ function pathSum(root: TreeNode | null, targetSum: number): number[][] {
};
```
-## Swift
+### Swift
-### 0112.路径总和
+0112.路径总和
**递归**
@@ -1141,7 +1143,7 @@ func hasPathSum(_ root: TreeNode?, _ targetSum: Int) -> Bool {
}
```
-### 0113.路径总和 II
+0113.路径总和 II
**递归**
@@ -1192,10 +1194,11 @@ func traversal(_ cur: TreeNode?, count: Int) {
}
```
-## C
+### C
-> 0112.路径总和
-> 递归法:
+0112.路径总和
+
+递归法:
```c
bool hasPathSum(struct TreeNode* root, int targetSum){
@@ -1252,7 +1255,7 @@ bool hasPathSum(struct TreeNode* root, int targetSum){
}
```
-> 0113.路径总和 II
+0113.路径总和 II
```c
int** ret;
@@ -1317,9 +1320,9 @@ int** pathSum(struct TreeNode* root, int targetSum, int* returnSize, int** retur
}
```
-## Scala
+### Scala
-### 0112.路径总和
+0112.路径总和
**递归:**
@@ -1369,7 +1372,7 @@ object Solution {
}
```
-### 0113.路径总和 II
+0113.路径总和 II
**递归:**
@@ -1405,9 +1408,9 @@ object Solution {
}
```
-## rust
+### Rust
-### 112.路径总和.md
+0112.路径总和
递归:
@@ -1461,7 +1464,7 @@ impl Solution {
}
```
-### 113.路径总和-ii
+0113.路径总和-ii
```rust
impl Solution {
diff --git a/problems/0115.不同的子序列.md b/problems/0115.不同的子序列.md
index 8c82880d..d925c5de 100644
--- a/problems/0115.不同的子序列.md
+++ b/problems/0115.不同的子序列.md
@@ -157,8 +157,8 @@ public:
## 其他语言版本
+### Java:
-Java:
```java
class Solution {
public int numDistinct(String s, String t) {
@@ -182,7 +182,8 @@ class Solution {
}
```
-Python:
+### Python:
+
```python
class Solution:
def numDistinct(self, s: str, t: str) -> int:
@@ -200,7 +201,8 @@ class Solution:
return dp[-1][-1]
```
-Python3:
+### Python3:
+
```python
class SolutionDP2:
"""
@@ -234,7 +236,8 @@ class SolutionDP2:
return dp[-1]
```
-Go:
+### Go:
+
```go
func numDistinct(s string, t string) int {
dp:= make([][]int,len(s)+1)
@@ -259,8 +262,8 @@ func numDistinct(s string, t string) int {
}
```
+### Javascript:
-Javascript:
```javascript
const numDistinct = (s, t) => {
let dp = Array.from(Array(s.length + 1), () => Array(t.length +1).fill(0));
@@ -283,7 +286,7 @@ const numDistinct = (s, t) => {
};
```
-TypeScript:
+### TypeScript:
```typescript
function numDistinct(s: string, t: string): number {
@@ -312,9 +315,8 @@ function numDistinct(s: string, t: string): number {
```
-
-
参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!
+
diff --git a/problems/0121.买卖股票的最佳时机.md b/problems/0121.买卖股票的最佳时机.md
index 06305156..cbdf40e8 100644
--- a/problems/0121.买卖股票的最佳时机.md
+++ b/problems/0121.买卖股票的最佳时机.md
@@ -24,11 +24,9 @@
* 输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。
-# 算法公开课
-
-**《代码随想录》算法视频公开课:[动态规划之 LeetCode:121.买卖股票的最佳时机1](https://www.bilibili.com/video/BV1Xe4y1u77q),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
-
+## 算法公开课
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划之 LeetCode:121.买卖股票的最佳时机1](https://www.bilibili.com/video/BV1Xe4y1u77q),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
## 思路
@@ -202,7 +200,7 @@ public:
## 其他语言版本
-Java:
+### Java:
> 贪心法:
@@ -294,8 +292,7 @@ class Solution {
```
-
-Python:
+### Python:
> 贪心法:
```python
@@ -351,7 +348,8 @@ class Solution:
return dp1
```
-Go:
+### Go:
+
> 贪心法:
```Go
func maxProfit(prices []int) int {
@@ -418,7 +416,7 @@ func max(a, b int) int {
}
```
-JavaScript:
+### JavaScript:
> 动态规划
@@ -454,7 +452,7 @@ var maxProfit = function(prices) {
};
```
-TypeScript:
+### TypeScript:
> 贪心法
@@ -492,7 +490,7 @@ function maxProfit(prices: number[]): number {
};
```
-C#:
+### C#:
> 贪心法
@@ -533,7 +531,7 @@ public class Solution
}
```
-Rust:
+### Rust:
> 贪心
diff --git a/problems/0122.买卖股票的最佳时机II.md b/problems/0122.买卖股票的最佳时机II.md
index 89c654fa..2c2ab225 100644
--- a/problems/0122.买卖股票的最佳时机II.md
+++ b/problems/0122.买卖股票的最佳时机II.md
@@ -37,9 +37,9 @@
- 1 <= prices.length <= 3 \* 10 ^ 4
- 0 <= prices[i] <= 10 ^ 4
-# 视频讲解
+## 算法公开课
-**《代码随想录》算法视频公开课:[贪心算法也能解决股票问题!LeetCode:122.买卖股票最佳时机 II](https://www.bilibili.com/video/BV1ev4y1C7na),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[贪心算法也能解决股票问题!LeetCode:122.买卖股票最佳时机 II](https://www.bilibili.com/video/BV1ev4y1C7na),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
## 思路
@@ -316,7 +316,7 @@ function maxProfit(prices: number[]): number {
}
```
-### Rust
+### Rust:
贪心:
@@ -389,7 +389,7 @@ int maxProfit(int* prices, int pricesSize){
}
```
-### Scala
+### Scala:
贪心:
@@ -411,3 +411,4 @@ object Solution {
+
diff --git a/problems/0122.买卖股票的最佳时机II(动态规划).md b/problems/0122.买卖股票的最佳时机II(动态规划).md
index 02f8d287..6e08b57c 100644
--- a/problems/0122.买卖股票的最佳时机II(动态规划).md
+++ b/problems/0122.买卖股票的最佳时机II(动态规划).md
@@ -34,9 +34,9 @@
* 1 <= prices.length <= 3 * 10 ^ 4
* 0 <= prices[i] <= 10 ^ 4
-# 算法公开课
+## 算法公开课
-**《代码随想录》算法视频公开课:[动态规划,股票问题第二弹 | LeetCode:122.买卖股票的最佳时机II](https://www.bilibili.com/video/BV1D24y1Q7Ls),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划,股票问题第二弹 | LeetCode:122.买卖股票的最佳时机II](https://www.bilibili.com/video/BV1D24y1Q7Ls),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
## 思路
@@ -133,8 +133,8 @@ public:
## 其他语言版本
+### Java:
-Java:
```java
// 动态规划
class Solution
@@ -191,7 +191,7 @@ class Solution {
}
```
-Python:
+### Python:
> 版本一:
```python
@@ -221,7 +221,8 @@ class Solution:
return dp[(length-1) % 2][1]
```
-Go:
+### Go:
+
```go
// 买卖股票的最佳时机Ⅱ 动态规划
// 时间复杂度:O(n) 空间复杂度:O(n)
@@ -250,7 +251,8 @@ func max(a, b int) int {
}
```
-Javascript:
+### JavaScript:
+
```javascript
// 方法一:动态规划(dp 数组)
const maxProfit = (prices) => {
@@ -290,7 +292,7 @@ const maxProfit = (prices) => {
}
```
-TypeScript:
+### TypeScript:
> 动态规划
@@ -326,7 +328,7 @@ function maxProfit(prices: number[]): number {
};
```
-C#:
+### C#:
> 贪心法
@@ -363,7 +365,7 @@ public class Solution
}
```
-Rust:
+### Rust:
> 贪心
@@ -414,4 +416,3 @@ impl Solution {
-
diff --git a/problems/0123.买卖股票的最佳时机III.md b/problems/0123.买卖股票的最佳时机III.md
index a646b7d5..72dd9042 100644
--- a/problems/0123.买卖股票的最佳时机III.md
+++ b/problems/0123.买卖股票的最佳时机III.md
@@ -39,9 +39,9 @@
* 1 <= prices.length <= 10^5
* 0 <= prices[i] <= 10^5
-# 算法公开课
+## 算法公开课
-**《代码随想录》算法视频公开课:[动态规划,股票至多买卖两次,怎么求? | LeetCode:123.买卖股票最佳时机III](https://www.bilibili.com/video/BV1WG411K7AR),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划,股票至多买卖两次,怎么求? | LeetCode:123.买卖股票最佳时机III](https://www.bilibili.com/video/BV1WG411K7AR),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
## 思路
@@ -221,7 +221,7 @@ public:
## 其他语言版本
-Java:
+### Java:
```java
// 版本一
@@ -277,7 +277,7 @@ class Solution {
}
```
-Python:
+### Python:
> 版本一:
```python
@@ -314,7 +314,7 @@ class Solution:
return dp[4]
```
-Go:
+### Go:
```go
func maxProfit(prices []int) int {
@@ -344,7 +344,7 @@ func max(a, b int) int {
}
```
-JavaScript:
+### JavaScript:
> 版本一:
@@ -383,7 +383,7 @@ const maxProfit = prices => {
};
```
-TypeScript:
+### TypeScript:
> 版本一
@@ -413,7 +413,7 @@ function maxProfit(prices: number[]): number {
};
```
-Rust:
+### Rust:
> 版本一
@@ -465,3 +465,4 @@ impl Solution {
+
diff --git a/problems/0131.分割回文串.md b/problems/0131.分割回文串.md
index 92fed58a..ca73e9f7 100644
--- a/problems/0131.分割回文串.md
+++ b/problems/0131.分割回文串.md
@@ -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> 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 {
+
diff --git a/problems/0134.加油站.md b/problems/0134.加油站.md
index ad9acfbc..2f9539e8 100644
--- a/problems/0134.加油站.md
+++ b/problems/0134.加油站.md
@@ -45,12 +45,14 @@
* 解释:
你不能从 0 号或 1 号加油站出发,因为没有足够的汽油可以让你行驶到下一个加油站。我们从 2 号加油站出发,可以获得 4 升汽油。 此时油箱有 = 0 + 4 = 4 升汽油。开往 0 号加油站,此时油箱有 4 - 3 + 2 = 3 升汽油。开往 1 号加油站,此时油箱有 3 - 3 + 3 = 3 升汽油。你无法返回 2 号加油站,因为返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。因此,无论怎样,你都不可能绕环路行驶一周。
-# 视频讲解
+## 算法公开课
-**《代码随想录》算法视频公开课:[贪心算法,得这么加油才能跑完全程!LeetCode :134.加油站](https://www.bilibili.com/video/BV1jA411r7WX),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[贪心算法,得这么加油才能跑完全程!LeetCode :134.加油站](https://www.bilibili.com/video/BV1jA411r7WX),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+
+## 思路
-## 暴力方法
+### 暴力方法
暴力的方法很明显就是O(n^2)的,遍历每一个加油站为起点的情况,模拟一圈。
@@ -85,7 +87,7 @@ public:
* 空间复杂度:O(1)
-## 贪心算法(方法一)
+### 贪心算法(方法一)
直接从全局进行贪心选择,情况如下:
@@ -134,7 +136,7 @@ public:
但不管怎么说,解法毕竟还是巧妙的,不用过于执着于其名字称呼。
-## 贪心算法(方法二)
+### 贪心算法(方法二)
可以换一个思路,首先如果总油量减去总消耗大于等于零那么一定可以跑完一圈,说明 各个站点的加油站 剩油量rest[i]相加一定是大于等于零的。
@@ -633,3 +635,4 @@ object Solution {
+
diff --git a/problems/0135.分发糖果.md b/problems/0135.分发糖果.md
index cf3ccc8e..d130bd68 100644
--- a/problems/0135.分发糖果.md
+++ b/problems/0135.分发糖果.md
@@ -28,9 +28,9 @@
* 输出: 4
* 解释: 你可以分别给这三个孩子分发 1、2、1 颗糖果。第三个孩子只得到 1 颗糖果,这已满足上述两个条件。
-# 视频讲解
+## 算法公开课
-**《代码随想录》算法视频公开课:[贪心算法,两者兼顾很容易顾此失彼!LeetCode:135.分发糖果](https://www.bilibili.com/video/BV1ev4y1r7wN),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[贪心算法,两者兼顾很容易顾此失彼!LeetCode:135.分发糖果](https://www.bilibili.com/video/BV1ev4y1r7wN),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
## 思路
@@ -234,7 +234,7 @@ func findMax(num1 int, num2 int) int {
}
```
-### Javascript:
+### Javascript
```Javascript
var candy = function(ratings) {
let candys = new Array(ratings.length).fill(1)
@@ -376,3 +376,4 @@ object Solution {
+
diff --git a/problems/0139.单词拆分.md b/problems/0139.单词拆分.md
index 0d88ba36..d93288ae 100644
--- a/problems/0139.单词拆分.md
+++ b/problems/0139.单词拆分.md
@@ -33,9 +33,9 @@
* 输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
* 输出: false
-# 算法公开课
+## 算法公开课
-**《代码随想录》算法视频公开课:[你的背包如何装满?| LeetCode:139.单词拆分](https://www.bilibili.com/video/BV1pd4y147Rh/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[你的背包如何装满?| LeetCode:139.单词拆分](https://www.bilibili.com/video/BV1pd4y147Rh/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
## 思路
@@ -123,7 +123,7 @@ public:
**这个代码就可以AC了,当然回溯算法不是本题的主菜,背包才是!**
-## 背包问题
+### 背包问题
单词就是物品,字符串s就是背包,单词能否组成字符串s,就是问物品能不能把背包装满。
@@ -239,7 +239,7 @@ public:
}
};
-```
+```
使用用例:s = "applepenapple", wordDict = ["apple", "pen"],对应的dp数组状态如下:
@@ -259,8 +259,8 @@ public:
## 其他语言版本
+### Java:
-Java:
```java
class Solution {
public boolean wordBreak(String s, List
+
diff --git a/problems/0150.逆波兰表达式求值.md b/problems/0150.逆波兰表达式求值.md
index 09cc4f96..663a68ea 100644
--- a/problems/0150.逆波兰表达式求值.md
+++ b/problems/0150.逆波兰表达式求值.md
@@ -5,8 +5,6 @@
+
diff --git a/problems/0188.买卖股票的最佳时机IV.md b/problems/0188.买卖股票的最佳时机IV.md
index 773a910a..d4dc7698 100644
--- a/problems/0188.买卖股票的最佳时机IV.md
+++ b/problems/0188.买卖股票的最佳时机IV.md
@@ -31,9 +31,9 @@
* 0 <= prices.length <= 1000
* 0 <= prices[i] <= 1000
-# 算法公开课
+## 算法公开课
-**《代码随想录》算法视频公开课:[动态规划来决定最佳时机,至多可以买卖K次!| LeetCode:188.买卖股票最佳时机4](https://www.bilibili.com/video/BV16M411U7XJ),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划来决定最佳时机,至多可以买卖K次!| LeetCode:188.买卖股票最佳时机4](https://www.bilibili.com/video/BV16M411U7XJ),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
## 思路
@@ -173,7 +173,7 @@ public:
## 其他语言版本
-Java:
+### Java:
```java
// 版本一: 三维 dp数组
@@ -295,7 +295,7 @@ class Solution {
}
```
-Python:
+### Python:
版本一
@@ -329,7 +329,7 @@ class Solution:
dp[j] = max(dp[j],dp[j-1]+prices[i])
return dp[2*k]
```
-Go:
+### Go:
版本一:
@@ -404,7 +404,7 @@ func max188(a, b int) int {
}
```
-Javascript:
+### JavaScript:
```javascript
// 方法一:动态规划
@@ -454,7 +454,7 @@ var maxProfit = function(k, prices) {
};
```
-TypeScript:
+### TypeScript:
```typescript
function maxProfit(k: number, prices: number[]): number {
@@ -474,7 +474,7 @@ function maxProfit(k: number, prices: number[]): number {
};
```
-Rust:
+### Rust:
```rust
impl Solution {
@@ -529,3 +529,4 @@ impl Solution {
+
diff --git a/problems/0198.打家劫舍.md b/problems/0198.打家劫舍.md
index 80902559..a7bc4c99 100644
--- a/problems/0198.打家劫舍.md
+++ b/problems/0198.打家劫舍.md
@@ -31,9 +31,9 @@
* 0 <= nums.length <= 100
* 0 <= nums[i] <= 400
-# 算法公开课
+## 算法公开课
-**《代码随想录》算法视频公开课:[动态规划,偷不偷这个房间呢?| LeetCode:198.打家劫舍](https://www.bilibili.com/video/BV1Te411N7SX),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划,偷不偷这个房间呢?| LeetCode:198.打家劫舍](https://www.bilibili.com/video/BV1Te411N7SX),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
## 思路
@@ -121,8 +121,8 @@ public:
## 其他语言版本
+### Java:
-Java:
```Java
// 动态规划
class Solution {
@@ -194,7 +194,7 @@ class Solution {
}
```
-Python:
+### Python:
1维DP
```python
@@ -255,7 +255,8 @@ class Solution:
```
-Go:
+### Go:
+
```Go
func rob(nums []int) int {
n := len(nums)
@@ -275,7 +276,7 @@ func max(a, b int) int {
}
```
-JavaScript:
+### JavaScript:
```javascript
const rob = nums => {
@@ -291,7 +292,7 @@ const rob = nums => {
};
```
-TypeScript:
+### TypeScript:
```typescript
function rob(nums: number[]): number {
@@ -314,7 +315,7 @@ function rob(nums: number[]): number {
};
```
-Rust:
+### Rust:
```rust
impl Solution {
@@ -338,4 +339,3 @@ impl Solution {
-
diff --git a/problems/0202.快乐数.md b/problems/0202.快乐数.md
index 7fe8cd8d..4a77e2b6 100644
--- a/problems/0202.快乐数.md
+++ b/problems/0202.快乐数.md
@@ -28,7 +28,7 @@
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
-# 思路
+## 思路
这道题目看上去貌似一道数学问题,其实并不是!
@@ -80,10 +80,10 @@ public:
-# 其他语言版本
+## 其他语言版本
+### Java:
-Java:
```java
class Solution {
public boolean isHappy(int n) {
@@ -107,8 +107,9 @@ class Solution {
}
```
-Python:
+### Python:
(版本一)使用集合
+
```python
class Solution:
def isHappy(self, n: int) -> bool:
@@ -131,7 +132,7 @@ class Solution:
n, r = divmod(n, 10)
new_num += r ** 2
return new_num
- ```
+```
(版本二)使用集合
```python
class Solution:
@@ -146,7 +147,7 @@ class Solution:
if new_num==1: return True
else: n = new_num
return False
-```
+ ```
(版本三)使用数组
```python
class Solution:
@@ -161,7 +162,7 @@ class Solution:
if new_num==1: return True
else: n = new_num
return False
-```
+ ```
(版本四)使用快慢指针
```python
class Solution:
@@ -180,7 +181,7 @@ class Solution:
n, r = divmod(n, 10)
new_num += r ** 2
return new_num
-```
+ ```
(版本五)使用集合+精简
```python
class Solution:
@@ -192,7 +193,7 @@ class Solution:
return False
seen.add(n)
return True
-```
+ ```
(版本六)使用数组+精简
```python
class Solution:
@@ -204,8 +205,9 @@ class Solution:
return False
seen.append(n)
return True
-```
-Go:
+ ```
+### Go:
+
```go
func isHappy(n int) bool {
m := make(map[int]bool)
@@ -225,7 +227,7 @@ func getSum(n int) int {
}
```
-javaScript:
+### JavaScript:
```js
var isHappy = function (n) {
@@ -303,7 +305,7 @@ var isHappy = function(n) {
};
```
-TypeScript:
+### TypeScript:
```typescript
function isHappy(n: number): boolean {
@@ -322,7 +324,7 @@ function isHappy(n: number): boolean {
};
```
-Swift:
+### Swift:
```swift
// number 每个位置上的数字的平方和
@@ -355,7 +357,8 @@ func isHappy(_ n: Int) -> Bool {
}
```
-PHP:
+### PHP:
+
```php
class Solution {
/**
@@ -386,7 +389,8 @@ class Solution {
}
```
-Rust:
+### Rust:
+
```Rust
use std::collections::HashSet;
impl Solution {
@@ -416,7 +420,8 @@ impl Solution {
}
```
-C:
+### C:
+
```C
typedef struct HashNodeTag {
int key; /* num */
@@ -473,8 +478,8 @@ object Solution {
}
```
+### C#:
-C#:
```csharp
public class Solution {
private int getSum(int n) {
@@ -500,3 +505,4 @@ public class Solution {
+
diff --git a/problems/0213.打家劫舍II.md b/problems/0213.打家劫舍II.md
index ee62b574..cd9d596d 100644
--- a/problems/0213.打家劫舍II.md
+++ b/problems/0213.打家劫舍II.md
@@ -31,9 +31,9 @@
* 1 <= nums.length <= 100
* 0 <= nums[i] <= 1000
-# 算法公开课
+## 算法公开课
-**《代码随想录》算法视频公开课:[动态规划,房间连成环了那还偷不偷呢?| LeetCode:213.打家劫舍II](https://www.bilibili.com/video/BV1oM411B7xq),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划,房间连成环了那还偷不偷呢?| LeetCode:213.打家劫舍II](https://www.bilibili.com/video/BV1oM411B7xq),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
## 思路
@@ -104,8 +104,8 @@ public:
## 其他语言版本
+### Java:
-Java:
```Java
class Solution {
public int rob(int[] nums) {
@@ -129,7 +129,7 @@ class Solution {
}
```
-Python:
+### Python:
```Python
class Solution:
@@ -219,7 +219,7 @@ class Solution:
```
-Go:
+### Go:
```go
// 打家劫舍Ⅱ 动态规划
@@ -257,7 +257,8 @@ func max(a, b int) int {
}
```
-javascipt:
+### JavaScript:
+
```javascript
var rob = function(nums) {
const n = nums.length
@@ -279,7 +280,7 @@ const robRange = (nums, start, end) => {
return dp[end]
}
```
-TypeScript:
+### TypeScript:
```typescript
function rob(nums: number[]): number {
@@ -301,7 +302,7 @@ function robRange(nums: number[], start: number, end: number): number {
}
```
-Rust:
+### Rust:
```rust
impl Solution {
@@ -336,3 +337,4 @@ impl Solution {
+
diff --git a/problems/0216.组合总和III.md b/problems/0216.组合总和III.md
index 319b2eba..4de7dc58 100644
--- a/problems/0216.组合总和III.md
+++ b/problems/0216.组合总和III.md
@@ -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 {
diff --git a/problems/0222.完全二叉树的节点个数.md b/problems/0222.完全二叉树的节点个数.md
index 795a6f37..d54f9b85 100644
--- a/problems/0222.完全二叉树的节点个数.md
+++ b/problems/0222.完全二叉树的节点个数.md
@@ -29,14 +29,17 @@
* 0 <= Node.val <= 5 * 10^4
* 题目数据保证输入的树是 完全二叉树
+## 算法公开课
-# 思路
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[要理解普通二叉树和完全二叉树的区别! | LeetCode:222.完全二叉树节点的数量](https://www.bilibili.com/video/BV1eW4y1B7pD),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
+
+
+## 思路
-《代码随想录》算法视频公开课:[要理解普通二叉树和完全二叉树的区别! | LeetCode:222.完全二叉树节点的数量](https://www.bilibili.com/video/BV1eW4y1B7pD),相信结合视频在看本篇题解,更有助于大家对本题的理解。
本篇给出按照普通二叉树的求法以及利用完全二叉树性质的求法。
-## 普通二叉树
+### 普通二叉树
首先按照普通二叉树的逻辑来求。
@@ -44,7 +47,7 @@
递归遍历的顺序依然是后序(左右中)。
-### 递归
+#### 递归
如果对求二叉树深度还不熟悉的话,看这篇:[二叉树:看看这些树的最大深度](https://programmercarl.com/0104.二叉树的最大深度.html)。
@@ -112,7 +115,7 @@ public:
**网上基本都是这个精简的代码版本,其实不建议大家照着这个来写,代码确实精简,但隐藏了一些内容,连遍历的顺序都看不出来,所以初学者建议学习版本一的代码,稳稳的打基础**。
-### 迭代法
+#### 迭代
如果对求二叉树层序遍历还不熟悉的话,看这篇:[二叉树:层序遍历登场!](https://programmercarl.com/0102.二叉树的层序遍历.html)。
@@ -142,7 +145,7 @@ public:
* 时间复杂度:O(n)
* 空间复杂度:O(n)
-## 完全二叉树
+### 完全二叉树
以上方法都是按照普通二叉树来做的,对于完全二叉树特性不了解的同学可以看这篇 [关于二叉树,你该了解这些!](https://programmercarl.com/二叉树理论基础.html),这篇详细介绍了各种二叉树的特性。
@@ -249,9 +252,9 @@ public:
* 时间复杂度:O(log n × log n)
* 空间复杂度:O(log n)
-# 其他语言版本
+## 其他语言版本
-## Java
+### Java:
```java
class Solution {
// 通用递归解法
@@ -312,7 +315,7 @@ class Solution {
}
```
-## Python
+### Python:
递归法:
```python
@@ -408,7 +411,7 @@ class Solution: # 利用完全二叉树特性
return 1+self.countNodes(root.left)+self.countNodes(root.right)
```
-## Go
+### Go:
递归版本
@@ -488,9 +491,7 @@ func countNodes(root *TreeNode) int {
}
```
-
-
-## JavaScript:
+### JavaScript:
递归版本
```javascript
@@ -559,7 +560,7 @@ var countNodes = function(root) {
};
```
-## TypeScrpt:
+### TypeScrpt:
> 递归法
@@ -614,7 +615,7 @@ function countNodes(root: TreeNode | null): number {
};
```
-## C:
+### C:
递归法
```c
@@ -690,7 +691,7 @@ int countNodes(struct TreeNode* root){
}
```
-## Swift:
+### Swift:
> 递归
```swift
@@ -758,7 +759,7 @@ func countNodes(_ root: TreeNode?) -> Int {
}
```
-## Scala
+### Scala:
递归:
```scala
@@ -821,9 +822,9 @@ object Solution {
}
```
-rust:
+### Rust:
-// 递归
+递归
```rust
use std::cell::RefCell;
use std::rc::Rc;
@@ -838,7 +839,7 @@ impl Solution {
}
```
-// 迭代
+迭代
```rust
use std::rc::Rc;
use std::cell::RefCell;
diff --git a/problems/0225.用队列实现栈.md b/problems/0225.用队列实现栈.md
index 94c79404..13b742f8 100644
--- a/problems/0225.用队列实现栈.md
+++ b/problems/0225.用队列实现栈.md
@@ -25,11 +25,11 @@
* 你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
* 你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。
+## 算法公开课
-# 思路
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[队列的基本操作! | LeetCode:225. 用队列实现栈](https://www.bilibili.com/video/BV1Fd4y1K7sm),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
-
-《代码随想录》算法公开课:[队列的基本操作! | LeetCode:225. 用队列实现栈](https://www.bilibili.com/video/BV1Fd4y1K7sm),相信结合视频再看本篇题解,更有助于大家对链表的理解。
+## 思路
(这里要强调是单向队列)
@@ -114,7 +114,7 @@ public:
* 时间复杂度: push为O(n),其他为O(1)
* 空间复杂度: O(n)
-# 优化
+## 优化
其实这道题目就是用一个队列就够了。
@@ -162,9 +162,9 @@ public:
* 空间复杂度: O(n)
-# 其他语言版本
+## 其他语言版本
-Java:
+### Java:
使用两个 Queue 实现方法1
```java
@@ -404,7 +404,7 @@ class MyStack {
}
```
-Python:
+### Python:
```python
from collections import deque
@@ -496,8 +496,7 @@ class MyStack:
return not self.que
```
-
-Go:
+### Go:
使用两个队列实现
```go
@@ -628,9 +627,7 @@ func (this *MyStack) Empty() bool {
*/
```
-
-
-javaScript:
+### JavaScript:
使用数组(push, shift)模拟队列
@@ -740,7 +737,7 @@ MyStack.prototype.empty = function() {
```
-TypeScript:
+### TypeScript:
版本一:使用两个队列模拟栈
@@ -812,7 +809,7 @@ class MyStack {
}
```
-Swift
+### Swift:
```Swift
// 定义一个队列数据结构
@@ -931,8 +928,9 @@ class MyStack {
}
}
```
-Scala:
+### Scala:
使用两个队列模拟栈:
+
```scala
import scala.collection.mutable
@@ -1015,8 +1013,8 @@ class MyStack() {
}
```
+### C#:
-C#:
```csharp
public class MyStack {
Queue
+
diff --git a/problems/0232.用栈实现队列.md b/problems/0232.用栈实现队列.md
index 4a57ee96..c510fc12 100644
--- a/problems/0232.用栈实现队列.md
+++ b/problems/0232.用栈实现队列.md
@@ -36,11 +36,12 @@ queue.empty(); // 返回 false
* 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
* 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。
+## 算法公开课
+
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[栈的基本操作! | LeetCode:232.用栈实现队列](https://www.bilibili.com/video/BV1nY4y1w7VC),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
+
## 思路
-《代码随想录》算法公开课:[栈的基本操作! | LeetCode:232.用栈实现队列](https://www.bilibili.com/video/BV1nY4y1w7VC),相信结合视频再看本篇题解,更有助于大家对栈和队列的理解。
-
-
这是一道模拟题,不涉及到具体算法,考察的就是对栈和队列的掌握程度。
使用栈来模式队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈**一个输入栈,一个输出栈**,这里要注意输入栈和输出栈的关系。
@@ -132,7 +133,7 @@ public:
## 其他语言版本
-Java:
+### Java:
```java
class MyQueue {
@@ -179,8 +180,8 @@ class MyQueue {
```
+### Python:
-Python:
```python
class MyQueue:
@@ -231,8 +232,8 @@ class MyQueue:
```
+### Go:
-Go:
```Go
type MyQueue struct {
stackIn []int //输入栈
@@ -283,7 +284,7 @@ func (this *MyQueue) Empty() bool {
}
```
- javaScript:
+### JavaScript:
```js
// 使用两个数组的栈方法(push, pop) 实现队列
@@ -338,7 +339,7 @@ MyQueue.prototype.empty = function() {
};
```
-TypeScript:
+### TypeScript:
```typescript
class MyQueue {
@@ -374,7 +375,7 @@ class MyQueue {
}
```
-Swift:
+### Swift:
```swift
class MyQueue {
@@ -413,7 +414,8 @@ class MyQueue {
}
```
-C:
+### C:
+
```C
/*
1.两个type为int的数组(栈),大小为100
@@ -490,8 +492,8 @@ void myQueueFree(MyQueue* obj) {
}
```
+### C#:
-C#:
```csharp
public class MyQueue {
Stack
-
diff --git a/problems/0235.二叉搜索树的最近公共祖先.md b/problems/0235.二叉搜索树的最近公共祖先.md
index 9777bb0b..2b8af060 100644
--- a/problems/0235.二叉搜索树的最近公共祖先.md
+++ b/problems/0235.二叉搜索树的最近公共祖先.md
@@ -36,11 +36,11 @@
* 所有节点的值都是唯一的。
* p、q 为不同节点且均存在于给定的二叉搜索树中。
-# 算法公开课
+## 算法公开课
-**《代码随想录》算法视频公开课:[二叉搜索树找祖先就有点不一样了!| 235. 二叉搜索树的最近公共祖先](https://www.bilibili.com/video/BV1Zt4y1F7ww?share_source=copy_web),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[二叉搜索树找祖先就有点不一样了!| 235. 二叉搜索树的最近公共祖先](https://www.bilibili.com/video/BV1Zt4y1F7ww?share_source=copy_web),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
-# 思路
+## 思路
做过[二叉树:公共祖先问题](https://programmercarl.com/0236.二叉树的最近公共祖先.html)题目的同学应该知道,利用回溯从底向上搜索,遇到一个节点的左子树里有p,右子树里有q,那么当前节点就是最近公共祖先。
@@ -71,7 +71,7 @@
可以看出直接按照指定的方向,就可以找到节点8,为最近公共祖先,而且不需要遍历整棵树,找到结果直接返回!
-## 递归法
+### 递归法
递归三部曲如下:
@@ -203,7 +203,7 @@ public:
};
```
-## 迭代法
+### 迭代法
对于二叉搜索树的迭代法,大家应该在[二叉树:二叉搜索树登场!](https://programmercarl.com/0700.二叉搜索树中的搜索.html)就了解了。
@@ -229,7 +229,7 @@ public:
灵魂拷问:是不是又被简单的迭代法感动到痛哭流涕?
-# 总结
+## 总结
对于二叉搜索树的最近祖先问题,其实要比[普通二叉树公共祖先问题](https://programmercarl.com/0236.二叉树的最近公共祖先.html)简单的多。
@@ -238,10 +238,10 @@ public:
最后给出了对应的迭代法,二叉搜索树的迭代法甚至比递归更容易理解,也是因为其有序性(自带方向性),按照目标区间找就行了。
-# 其他语言版本
+## 其他语言版本
-## Java
+### Java
递归法:
```java
@@ -273,7 +273,7 @@ class Solution {
```
-## Python
+### Python
递归法(版本一)
```python
@@ -326,7 +326,7 @@ class Solution:
```
-## Go
+### Go
递归法:
```go
@@ -350,7 +350,7 @@ func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
```
-## JavaScript
+### JavaScript
递归法:
```javascript
@@ -391,7 +391,7 @@ var lowestCommonAncestor = function(root, p, q) {
};
```
-## TypeScript
+### TypeScript
> 递归法:
@@ -422,7 +422,7 @@ function lowestCommonAncestor(root: TreeNode | null, p: TreeNode | null, q: Tree
};
```
-## Scala
+### Scala
递归:
@@ -453,7 +453,7 @@ object Solution {
}
```
-## rust
+### Rust
递归:
@@ -519,3 +519,4 @@ impl Solution {
+
diff --git a/problems/0236.二叉树的最近公共祖先.md b/problems/0236.二叉树的最近公共祖先.md
index 0ebd5566..9db7409e 100644
--- a/problems/0236.二叉树的最近公共祖先.md
+++ b/problems/0236.二叉树的最近公共祖先.md
@@ -34,12 +34,12 @@
* 所有节点的值都是唯一的。
* p、q 为不同节点且均存在于给定的二叉树中。
-# 算法公开课
+## 算法公开课
-**《代码随想录》算法视频公开课:[自底向上查找,有点难度! | LeetCode:236. 二叉树的最近公共祖先](https://www.bilibili.com/video/BV1jd4y1B7E2),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[自底向上查找,有点难度! | LeetCode:236. 二叉树的最近公共祖先](https://www.bilibili.com/video/BV1jd4y1B7E2),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
-# 思路
+## 思路
遇到这个题目首先想的是要是能自底向上查找就好了,这样就可以找到公共祖先了。
@@ -226,7 +226,7 @@ public:
};
```
-# 总结
+## 总结
这道题目刷过的同学未必真正了解这里面回溯的过程,以及结果是如何一层一层传上去的。
@@ -243,10 +243,10 @@ public:
本题没有给出迭代法,因为迭代法不适合模拟回溯的过程。理解递归的解法就够了。
-# 其他语言版本
+## 其他语言版本
-## Java
+### Java
```Java
class Solution {
@@ -273,7 +273,7 @@ class Solution {
```
-## Python
+### Python
递归法(版本一)
```python
class Solution:
@@ -312,7 +312,7 @@ class Solution:
return left
```
-## Go
+### Go
```Go
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
@@ -343,7 +343,7 @@ func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
}
```
-## JavaScript
+### JavaScript
```javascript
var lowestCommonAncestor = function(root, p, q) {
@@ -370,7 +370,7 @@ var lowestCommonAncestor = function(root, p, q) {
};
```
-## TypeScript
+### TypeScript
```typescript
function lowestCommonAncestor(root: TreeNode | null, p: TreeNode | null, q: TreeNode | null): TreeNode | null {
@@ -384,7 +384,7 @@ function lowestCommonAncestor(root: TreeNode | null, p: TreeNode | null, q: Tree
};
```
-## Scala
+### Scala
```scala
object Solution {
@@ -404,7 +404,7 @@ object Solution {
}
```
-## rust
+### Rust
```rust
impl Solution {
@@ -436,3 +436,4 @@ impl Solution {
+
diff --git a/problems/0239.滑动窗口最大值.md b/problems/0239.滑动窗口最大值.md
index f1c4b76c..6f420479 100644
--- a/problems/0239.滑动窗口最大值.md
+++ b/problems/0239.滑动窗口最大值.md
@@ -28,11 +28,11 @@
* -10^4 <= nums[i] <= 10^4
* 1 <= k <= nums.length
+## 算法公开课
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[单调队列正式登场!| LeetCode:239. 滑动窗口最大值](https://www.bilibili.com/video/BV1XS4y1p7qj),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
-# 思路
-
-《代码随想录》算法视频公开课:[单调队列正式登场!| LeetCode:239. 滑动窗口最大值](https://www.bilibili.com/video/BV1XS4y1p7qj),相信结合视频在看本篇题解,更有助于大家对本题的理解。
+## 思路
这是使用单调队列的经典题目。
@@ -196,7 +196,7 @@ public:
空间复杂度因为我们定义一个辅助队列,所以是O(k)。
-# 扩展
+## 扩展
大家貌似对单调队列 都有一些疑惑,首先要明确的是,题解中单调队列里的pop和push接口,仅适用于本题哈。单调队列不是一成不变的,而是不同场景不同写法,总之要保证队列里单调递减或递增的原则,所以叫做单调队列。 不要以为本题中的单调队列实现就是固定的写法哈。
@@ -204,10 +204,10 @@ public:
-# 其他语言版本
+## 其他语言版本
+### Java:
-Java:
```Java
//解法一
//自定义数组
@@ -298,7 +298,8 @@ class Solution {
}
```
-Python:
+### Python:
+
```python
from collections import deque
@@ -338,8 +339,7 @@ class Solution:
return result
```
-
-Go:
+### Go:
```go
// 封装单调队列的方式解题
@@ -401,7 +401,8 @@ func maxSlidingWindow(nums []int, k int) []int {
}
```
-Javascript:
+### Javascript:
+
```javascript
/**
* @param {number[]} nums
@@ -449,7 +450,7 @@ var maxSlidingWindow = function (nums, k) {
};
```
-TypeScript:
+### TypeScript:
```typescript
function maxSlidingWindow(nums: number[], k: number): number[] {
@@ -497,7 +498,9 @@ function maxSlidingWindow(nums: number[], k: number): number[] {
};
```
-Swift:
+### Swift:
+
+解法一:
```Swift
/// 双向链表
@@ -638,7 +641,8 @@ func maxSlidingWindow(_ nums: [Int], _ k: Int) -> [Int] {
return result
}
```
-Scala:
+### Scala:
+
```scala
import scala.collection.mutable.ArrayBuffer
object Solution {
@@ -686,8 +690,8 @@ class MyQueue {
}
```
+### PHP:
-PHP:
```php
class Solution {
/**
@@ -764,7 +768,8 @@ class MyQueue{
}
```
-C#:
+### C#:
+
```csharp
class myDequeue{
private LinkedList
+
diff --git a/problems/0257.二叉树的所有路径.md b/problems/0257.二叉树的所有路径.md
index 06153507..44c0fd85 100644
--- a/problems/0257.二叉树的所有路径.md
+++ b/problems/0257.二叉树的所有路径.md
@@ -18,9 +18,11 @@
示例:

-# 思路
+## 算法公开课
-**《代码随想录》算法视频公开课:[递归中带着回溯,你感受到了没?| LeetCode:257. 二叉树的所有路径](https://www.bilibili.com/video/BV1ZG411G7Dh),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html)::[递归中带着回溯,你感受到了没?| LeetCode:257. 二叉树的所有路径](https://www.bilibili.com/video/BV1ZG411G7Dh),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+
+## 思路
这道题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。
@@ -32,7 +34,7 @@
我们先使用递归的方式,来做前序遍历。**要知道递归和回溯就是一家的,本题也需要回溯。**
-## 递归
+### 递归
1. 递归函数参数以及返回值
@@ -305,7 +307,7 @@ public:
**综合以上,第二种递归的代码虽然精简但把很多重要的点隐藏在了代码细节里,第一种递归写法虽然代码多一些,但是把每一个逻辑处理都完整的展现出来了。**
-## 拓展
+### 拓展
这里讲解本题解的写法逻辑以及一些更具体的细节,下面的讲解中,涉及到C++语法特性,如果不是C++的录友,就可以不看了,避免越看越晕。
@@ -328,7 +330,7 @@ public:
所以,第一个代码版本中,我才使用 vector 类型的path,这样方便给大家演示代码中回溯的操作。 vector类型的path,不管 每次 路径收集的数字是几位数,总之一定是int,所以就一次 pop_back就可以。
-## 迭代法
+### 迭代法
至于非递归的方式,我们可以依然可以使用前序遍历的迭代方式来模拟遍历路径的过程,对该迭代方式不了解的同学,可以看文章[二叉树:听说递归能做的,栈也能做!](https://programmercarl.com/二叉树的迭代遍历.html)和[二叉树:前中后序迭代方式统一写法](https://programmercarl.com/二叉树的统一迭代法.html)。
@@ -368,7 +370,7 @@ public:
```
当然,使用java的同学,可以直接定义一个成员变量为object的栈`Stack