diff --git a/README.md b/README.md
index 3dbf2c0d..02d004e9 100644
--- a/README.md
+++ b/README.md
@@ -3,35 +3,22 @@
👉 推荐 [Gitee同步](https://gitee.com/programmercarl/leetcode-master)
> 1. **介绍**:本项目是一套完整的刷题计划,旨在帮助大家少走弯路,循序渐进学算法,[关注作者](#关于作者)
-> 2. **PDF版本** : [「代码随想录」算法精讲 PDF 版本](https://programmercarl.com/other/algo_pdf.html) 。
-> 3. **算法公开课** : [《代码随想录》算法视频公开课](https://www.bilibili.com/video/BV1fA4y1o715) 。
-> 4. **最强八股文:**:[代码随想录知识星球精华PDF](https://www.programmercarl.com/other/kstar_baguwen.html)
-> 5. **刷题顺序** : README已经将刷题顺序排好了,按照顺序一道一道刷就可以。
-> 6. **学习社区** : 一起学习打卡/面试技巧/如何选择offer/大厂内推/职场规则/简历修改/技术分享/程序人生。欢迎加入[「代码随想录」知识星球](https://programmercarl.com/other/kstar.html) 。
-> 7. **提交代码**:本项目统一使用C++语言进行讲解,但已经有Java、Python、Go、JavaScript等等多语言版本,感谢[这里的每一位贡献者](https://github.com/youngyangyang04/leetcode-master/graphs/contributors),如果你也想贡献代码点亮你的头像,[点击这里](https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A)了解提交代码的方式。
-> 8. **转载须知** :以下所有文章皆为我([程序员Carl](https://github.com/youngyangyang04))的原创。引用本项目文章请注明出处,发现恶意抄袭或搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境!
+> 2. **正式出版** :[《代码随想录》](https://programmercarl.com/other/publish.html) 。
+> 3. **PDF版本** : [「代码随想录」算法精讲 PDF 版本](https://programmercarl.com/other/algo_pdf.html) 。
+> 4. **算法公开课** : [《代码随想录》算法视频公开课](https://www.bilibili.com/video/BV1fA4y1o715) 。
+> 5. **最强八股文:**:[代码随想录知识星球精华PDF](https://www.programmercarl.com/other/kstar_baguwen.html)
+> 6. **刷题顺序** : README已经将刷题顺序排好了,按照顺序一道一道刷就可以。
+> 7. **学习社区** : 一起学习打卡/面试技巧/如何选择offer/大厂内推/职场规则/简历修改/技术分享/程序人生。欢迎加入[「代码随想录」知识星球](https://programmercarl.com/other/kstar.html) 。
+> 8. **提交代码**:本项目统一使用C++语言进行讲解,但已经有Java、Python、Go、JavaScript等等多语言版本,感谢[这里的每一位贡献者](https://github.com/youngyangyang04/leetcode-master/graphs/contributors),如果你也想贡献代码点亮你的头像,[点击这里](https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A)了解提交代码的方式。
+> 9. **转载须知** :以下所有文章皆为我([程序员Carl](https://github.com/youngyangyang04))的原创。引用本项目文章请注明出处,发现恶意抄袭或搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境!
+
-
-
-
-
-
-
-
-
-
-
-
-《代码随想录》正式出版啦!!录友专属福利,点击下方可以享五折优惠!详细可以点击这里
-
-
-
-
+
+
-
# LeetCode 刷题攻略
## 刷题攻略的背景
diff --git a/problems/0077.组合.md b/problems/0077.组合.md
index 9c473bdd..4ce58d33 100644
--- a/problems/0077.组合.md
+++ b/problems/0077.组合.md
@@ -25,9 +25,13 @@
[1,4],
]
-也可以直接看我的B站视频:[带你学透回溯算法-组合问题(对应力扣题目:77.组合)](https://www.bilibili.com/video/BV1ti4y1L7cv#reply3733925949)
+# 算法公开课
-## 思路
+
+**《代码随想录》算法视频公开课:[带你学透回溯算法-组合问题(对应力扣题目:77.组合)](https://www.bilibili.com/video/BV1ti4y1L7cv),[组合问题的剪枝操作](https://www.bilibili.com/video/BV1wi4y157er),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+
+
+# 思路
本题这是回溯法的经典题目。
@@ -122,7 +126,7 @@ vector path; // 用来存放符合条件结果
为什么要有这个startIndex呢?
-**每次从集合中选取元素,可选择的范围随着选择的进行而收缩,调整可选择的范围,就是要靠startIndex**。
+**建议在[77.组合视频讲解](https://www.bilibili.com/video/BV1ti4y1L7cv)中,07:36的时候开始听,startIndex 就是防止出现重复的组合**。
从下图中红线部分可以看出,在集合[1,2,3,4]取1之后,下一层递归,就要在[2,3,4]中取数了,那么下一层递归如何知道从[2,3,4]中取数呢,靠的就是startIndex。
diff --git a/problems/0077.组合优化.md b/problems/0077.组合优化.md
index b8b5f3c1..c8a5837d 100644
--- a/problems/0077.组合优化.md
+++ b/problems/0077.组合优化.md
@@ -6,12 +6,12 @@
+# 77.组合优化
+**《代码随想录》算法视频公开课:[组合问题的剪枝操作](https://www.bilibili.com/video/BV1wi4y157er),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
在[回溯算法:求组合问题!](https://programmercarl.com/0077.组合.html)中,我们通过回溯搜索法,解决了n个数中求k个数的组合问题。
-> 可以直接看我的B栈视频讲解:[带你学透回溯算法-组合问题的剪枝操作](https://www.bilibili.com/video/BV1wi4y157er)
-
文中的回溯法是可以剪枝优化的,本篇我们继续来看一下题目77. 组合。
链接:https://leetcode.cn/problems/combinations/
@@ -84,9 +84,11 @@ for (int i = startIndex; i <= n; i++) {
1. 已经选择的元素个数:path.size();
-2. 还需要的元素个数为: k - path.size();
+2. 所需需要的元素个数为: k - path.size();
-3. 在集合n中至多要从该起始位置 : n - (k - path.size()) + 1,开始遍历
+3. 列表中剩余元素(n-i) >= 所需需要的元素个数(k - path.size())
+
+4. 在集合n中至多要从该起始位置 : i <= n - (k - path.size()) + 1,开始遍历
为什么有个+1呢,因为包括起始位置,我们要是一个左闭的集合。
diff --git a/problems/0098.验证二叉搜索树.md b/problems/0098.验证二叉搜索树.md
index 727144d5..5deaed52 100644
--- a/problems/0098.验证二叉搜索树.md
+++ b/problems/0098.验证二叉搜索树.md
@@ -20,6 +20,11 @@

+# 视频讲解
+
+**《代码随想录》算法视频公开课:[你对二叉搜索树了解的还不够! | LeetCode:98.验证二叉搜索树](https://www.bilibili.com/video/BV18P411n7Q4),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+
+
# 思路
要知道中序遍历下,输出的二叉搜索树节点的数值是有序序列。
diff --git a/problems/0108.将有序数组转换为二叉搜索树.md b/problems/0108.将有序数组转换为二叉搜索树.md
index b5f322f0..f9f8a4ff 100644
--- a/problems/0108.将有序数组转换为二叉搜索树.md
+++ b/problems/0108.将有序数组转换为二叉搜索树.md
@@ -31,9 +31,17 @@
进入正题:
-题目中说要转换为一棵高度平衡二叉搜索树。这和转换为一棵普通二叉搜索树有什么差别呢?
+题目中说要转换为一棵高度平衡二叉搜索树。为什么强调要平衡呢?
-其实这里不用强调平衡二叉搜索树,数组构造二叉树,构成平衡树是自然而然的事情,因为大家默认都是从数组中间位置取值作为节点元素,一般不会随机取,**所以想构成不平衡的二叉树是自找麻烦**。
+因为只要给我们一个有序数组,如果强调平衡,都可以以线性结构来构造二叉搜索树。
+
+例如 有序数组[-10,-3,0,5,9] 可以就可以构造成这样的二叉搜索树,如图。
+
+
+
+上图中,是符合二叉搜索树的特性吧,如果要这么做的话,是不是本题意义就不大了,所以才强调是平衡二叉搜索树。
+
+其实数组构造二叉树,构成平衡树是自然而然的事情,因为大家默认都是从数组中间位置取值作为节点元素,一般不会随机取。**所以想构成不平衡的二叉树是自找麻烦**。
在[二叉树:构造二叉树登场!](https://programmercarl.com/0106.从中序与后序遍历序列构造二叉树.html)和[二叉树:构造一棵最大的二叉树](https://programmercarl.com/0654.最大二叉树.html)中其实已经讲过了,如果根据数组构造一棵二叉树。
diff --git a/problems/0150.逆波兰表达式求值.md b/problems/0150.逆波兰表达式求值.md
index 13b2ba46..306af14b 100644
--- a/problems/0150.逆波兰表达式求值.md
+++ b/problems/0150.逆波兰表达式求值.md
@@ -89,19 +89,19 @@ C++代码如下:
class Solution {
public:
int evalRPN(vector& tokens) {
- stack st;
+ stack st;
for (int i = 0; i < tokens.size(); i++) {
if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") {
- int num1 = st.top();
+ long long num1 = st.top();
st.pop();
- int num2 = st.top();
+ long long num2 = st.top();
st.pop();
if (tokens[i] == "+") st.push(num2 + num1);
if (tokens[i] == "-") st.push(num2 - num1);
- if (tokens[i] == "*") st.push((long)num2 * (long)num1); //力扣改了后台测试数据
+ if (tokens[i] == "*") st.push(num2 * num1);
if (tokens[i] == "/") st.push(num2 / num1);
} else {
- st.push(stoi(tokens[i]));
+ st.push(stoll(tokens[i]));
}
}
int result = st.top();
diff --git a/problems/0216.组合总和III.md b/problems/0216.组合总和III.md
index 964facee..ecd3a2c9 100644
--- a/problems/0216.组合总和III.md
+++ b/problems/0216.组合总和III.md
@@ -7,7 +7,7 @@
-> 别看本篇选的是组合总和III,而不是组合总和,本题和上一篇[回溯算法:求组合问题!](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)相比难度刚刚好!
+> 别看本篇选的是组合总和III,而不是组合总和,本题和上一篇77.组合相比难度刚刚好!
# 216.组合总和III
@@ -166,7 +166,7 @@ public:
已选元素总和如果已经大于n(图中数值为4)了,那么往后遍历就没有意义了,直接剪掉。
-那么剪枝的地方一定是在递归终止的地方剪,剪枝代码如下:
+那么剪枝的地方可以放在递归函数开始的地方,剪枝代码如下:
```cpp
if (sum > targetSum) { // 剪枝操作
@@ -174,6 +174,25 @@ if (sum > targetSum) { // 剪枝操作
}
```
+当然这个剪枝也可以放在 调用递归之前,即放在这里,只不过要记得 要回溯操作给做了。
+
+```CPP
+
+for (int i = startIndex; i <= 9 - (k - path.size()) + 1; i++) { // 剪枝
+ sum += i; // 处理
+ path.push_back(i); // 处理
+ if (sum > targetSum) { // 剪枝操作
+ sum -= i; // 剪枝之前先把回溯做了
+ path.pop_back(); // 剪枝之前先把回溯做了
+ return;
+ }
+ backtracking(targetSum, k, sum, i + 1); // 注意i+1调整startIndex
+ sum -= i; // 回溯
+ path.pop_back(); // 回溯
+}
+```
+
+
和[回溯算法:组合问题再剪剪枝](https://programmercarl.com/0077.组合优化.html) 一样,for循环的范围也可以剪枝,i <= 9 - (k - path.size()) + 1就可以了。
最后C++代码如下:
@@ -224,7 +243,7 @@ public:
# 其他语言版本
-## Java
+## Java
模板方法
```java
@@ -247,7 +266,7 @@ class Solution {
if (sum == targetSum) result.add(new ArrayList<>(path));
return;
}
-
+
// 减枝 9 - (k - path.size()) + 1
for (int i = startIndex; i <= 9 - (k - path.size()) + 1; i++) {
path.add(i);
@@ -272,7 +291,7 @@ class Solution {
}
private void build(int k, int n, int startIndex, int sum) {
-
+
if (sum > n) return;
if (path.size() > k) return;
@@ -281,7 +300,7 @@ class Solution {
ans.add(new ArrayList<>(path));
return;
}
-
+
for(int i = startIndex; i <= 9; i++) {
path.add(i);
sum += i;
@@ -328,7 +347,7 @@ class Solution {
}
```
-## Python
+## Python
```py
class Solution:
@@ -492,7 +511,7 @@ void backtracking(int targetSum, int k, int sum, int startIndex) {
if(sum == targetSum) {
int* tempPath = (int*)malloc(sizeof(int) * k);
int j;
- for(j = 0; j < k; j++)
+ for(j = 0; j < k; j++)
tempPath[j] = path[j];
ans[ansTop++] = tempPath;
}
@@ -580,7 +599,7 @@ object Solution {
// 剪枝
for (i <- startIndex to (9 - (k - path.size) + 1)) {
path.append(i)
- backtracking(k, n, sum + i, i + 1)
+ backtracking(k, n, sum + i, i + 1)
path = path.take(path.size - 1)
}
}
@@ -592,5 +611,7 @@ object Solution {
```
+
+
-----------------------
diff --git a/problems/0236.二叉树的最近公共祖先.md b/problems/0236.二叉树的最近公共祖先.md
index 82ca09f0..e982493f 100644
--- a/problems/0236.二叉树的最近公共祖先.md
+++ b/problems/0236.二叉树的最近公共祖先.md
@@ -33,6 +33,11 @@
* 所有节点的值都是唯一的。
* p、q 为不同节点且均存在于给定的二叉树中。
+# 算法公开课
+
+**《代码随想录》算法视频公开课:[自底向上查找,有点难度! | LeetCode:236. 二叉树的最近公共祖先](https://www.bilibili.com/video/BV1jd4y1B7E2),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+
+
# 思路
遇到这个题目首先想的是要是能自底向上查找就好了,这样就可以找到公共祖先了。
diff --git a/problems/0501.二叉搜索树中的众数.md b/problems/0501.二叉搜索树中的众数.md
index a2fdddf4..66919419 100644
--- a/problems/0501.二叉搜索树中的众数.md
+++ b/problems/0501.二叉搜索树中的众数.md
@@ -33,6 +33,11 @@
进阶:你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)
+# 算法公开课
+
+**《代码随想录》算法视频公开课:[不仅双指针,还有代码技巧可以惊艳到你! | LeetCode:501.二叉搜索树中的众数](https://www.bilibili.com/video/BV1fD4y117gp),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+
+
# 思路
这道题目呢,递归法我从两个维度来讲。
diff --git a/problems/0530.二叉搜索树的最小绝对差.md b/problems/0530.二叉搜索树的最小绝对差.md
index af1cbd74..811ae89c 100644
--- a/problems/0530.二叉搜索树的最小绝对差.md
+++ b/problems/0530.二叉搜索树的最小绝对差.md
@@ -19,6 +19,11 @@
提示:树中至少有 2 个节点。
+# 视频讲解
+
+**《代码随想录》算法视频公开课:[二叉搜索树中,需要掌握如何双指针遍历!| LeetCode:530.二叉搜索树的最小绝对差](https://www.bilibili.com/video/BV1DD4y11779),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
+
+
# 思路
题目中要求在二叉搜索树上任意两节点的差的绝对值的最小值。
diff --git a/problems/0538.把二叉搜索树转换为累加树.md b/problems/0538.把二叉搜索树转换为累加树.md
index 5c1e9e8c..63c931d6 100644
--- a/problems/0538.把二叉搜索树转换为累加树.md
+++ b/problems/0538.把二叉搜索树转换为累加树.md
@@ -78,7 +78,7 @@ pre指针的使用技巧,我们在[二叉树:搜索树的最小绝对差](ht
代码如下:
```
-int pre; // 记录前一个节点的数值
+int pre = 0; // 记录前一个节点的数值
void traversal(TreeNode* cur)
```
@@ -108,7 +108,7 @@ traversal(cur->left); // 左
```CPP
class Solution {
private:
- int pre; // 记录前一个节点的数值
+ int pre = 0; // 记录前一个节点的数值
void traversal(TreeNode* cur) { // 右中左遍历
if (cur == NULL) return;
traversal(cur->right);
diff --git a/problems/0704.二分查找.md b/problems/0704.二分查找.md
index d1389549..b1eaf75a 100644
--- a/problems/0704.二分查找.md
+++ b/problems/0704.二分查找.md
@@ -223,18 +223,18 @@ class Solution:
```python
class Solution:
def search(self, nums: List[int], target: int) -> int:
- if nums is None or len(nums)==0:
- return -1
- left,right=0,len(nums)
- while (left target:
- right=middle
+ right = middle
else:
- left=middle+1
- return -1
+ return middle
+ return -1
```
**Go:**