diff --git a/README.md b/README.md
index ad22aeab8e..40cd272f60 100644
--- a/README.md
+++ b/README.md
@@ -71,7 +71,7 @@
**这里每一篇题解,都是精品,值得仔细琢磨**。
-我在题目讲解中统一用C++语言,但你会发现下面几乎每篇题解都配有其他语言版本,Java、Python、Go、JavaScript等等,这正是热心小伙们的贡献的代码,当然我也会严格把控代码质量。
+我在题目讲解中统一使用C++,但你会发现下面几乎每篇题解都配有其他语言版本,Java、Python、Go、JavaScript等等,正是这些[热心小伙们](https://github.com/youngyangyang04/leetcode-master/graphs/contributors)的贡献的代码,当然我也会严格把控代码质量。
**所以也欢迎大家参与进来,完善题解的各个语言版本,拥抱开源,让更多小伙伴们收益**。
@@ -133,6 +133,13 @@
9. [秋招和提前批都越来越提前了....](https://mp.weixin.qq.com/s/SNFiRDx8CKyjhTPlys6ywQ)
10. [你的简历里「专业技能」写的够专业么?](https://mp.weixin.qq.com/s/bp6y-e5FVN28H9qc8J9zrg)
11. [对于秋招,实习生也有烦恼....](https://mp.weixin.qq.com/s/ka07IPryFnfmIjByFFcXDg)
+12. [华为提前批已经开始了.....](https://mp.weixin.qq.com/s/OC35QDG8pn5OwLpCxieStw)
+13. [大厂新人培养体系应该是什么样的?](https://mp.weixin.qq.com/s/WBaPCosOljB5NEkFL2GhOQ)
+
+## 杂谈
+
+[大半年过去了......](https://mp.weixin.qq.com/s/lubfeistPxBLSQIe5XYg5g)
+
## 数组
@@ -161,14 +168,15 @@
1. [关于哈希表,你该了解这些!](./problems/哈希表理论基础.md)
2. [哈希表:可以拿数组当哈希表来用,但哈希值不要太大](./problems/0242.有效的字母异位词.md)
-3. [哈希表:哈希值太大了,还是得用set](./problems/0349.两个数组的交集.md)
-4. [哈希表:用set来判断快乐数](./problems/0202.快乐数.md)
-5. [哈希表:map等候多时了](./problems/0001.两数之和.md)
-6. [哈希表:其实需要哈希的地方都能找到map的身影](./problems/0454.四数相加II.md)
-7. [哈希表:这道题目我做过?](./problems/0383.赎金信.md)
-8. [哈希表:解决了两数之和,那么能解决三数之和么?](./problems/0015.三数之和.md)
-9. [双指针法:一样的道理,能解决四数之和](./problems/0018.四数之和.md)
-10. [哈希表:总结篇!(每逢总结必经典)](./problems/哈希表总结.md)
+3. [哈希表:查找常用字符](./problems/1002.查找常用字符.md)
+4. [哈希表:哈希值太大了,还是得用set](./problems/0349.两个数组的交集.md)
+5. [哈希表:用set来判断快乐数](./problems/0202.快乐数.md)
+6. [哈希表:map等候多时了](./problems/0001.两数之和.md)
+7. [哈希表:其实需要哈希的地方都能找到map的身影](./problems/0454.四数相加II.md)
+8. [哈希表:这道题目我做过?](./problems/0383.赎金信.md)
+9. [哈希表:解决了两数之和,那么能解决三数之和么?](./problems/0015.三数之和.md)
+10. [双指针法:一样的道理,能解决四数之和](./problems/0018.四数之和.md)
+11. [哈希表:总结篇!(每逢总结必经典)](./problems/哈希表总结.md)
## 字符串
@@ -444,7 +452,7 @@
# 贡献者
-你可以[点此链接](https://github.com/youngyangyang04/leetcode-master/graphs/contributors)查看LeetCode-Master的所有贡献者。感谢你们补充了LeetCode-Master的其他语言版本,让更多的读者收益于此项目。
+[点此这里](https://github.com/youngyangyang04/leetcode-master/graphs/contributors)查看LeetCode-Master的所有贡献者。感谢他们补充了LeetCode-Master的其他语言版本,让更多的读者收益于此项目。
# 关于作者
@@ -459,7 +467,7 @@
# 公众号
-更多精彩文章持续更新,微信搜索:「代码随想录」第一时间围观,关注后回复:「666」可以获得所有算法专题原创PDF。
+更多精彩文章持续更新,微信搜索:「代码随想录」第一时间围观,关注后回复:666,可以获得我的所有算法专题原创PDF。
**「代码随想录」每天准时为你推送一篇经典面试题目,帮你梳理算法知识体系,轻松学习算法!**,并且公众号里有大量学习资源,也有我自己的学习心得和方法总结,更有上万录友们在这里打卡学习。
diff --git "a/problems/0028.\345\256\236\347\216\260strStr.md" "b/problems/0028.\345\256\236\347\216\260strStr.md"
index aaa28d3d70..69f8c9d6f2 100644
--- "a/problems/0028.\345\256\236\347\216\260strStr.md"
+++ "b/problems/0028.\345\256\236\347\216\260strStr.md"
@@ -651,7 +651,7 @@ class Solution {
}
```
-Python:
+Python3:
```python
// 方法一
diff --git "a/problems/0042.\346\216\245\351\233\250\346\260\264.md" "b/problems/0042.\346\216\245\351\233\250\346\260\264.md"
index 55a5c52205..70a4e07c2a 100644
--- "a/problems/0042.\346\216\245\351\233\250\346\260\264.md"
+++ "b/problems/0042.\346\216\245\351\233\250\346\260\264.md"
@@ -1,4 +1,13 @@
+
+
+
+
+
+
+欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!
+
+> 这个图就是大厂面试经典题目,接雨水! 最常青藤的一道题,面试官百出不厌!
# 42. 接雨水
@@ -355,3 +364,9 @@ public:
## 其他语言版本
+
+-----------------------
+* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
+* B站视频:[代码随想录](https://space.bilibili.com/525438321)
+* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
+
diff --git "a/problems/0059.\350\236\272\346\227\213\347\237\251\351\230\265II.md" "b/problems/0059.\350\236\272\346\227\213\347\237\251\351\230\265II.md"
index 6d8ec99cd1..90b7400597 100644
--- "a/problems/0059.\350\236\272\346\227\213\347\237\251\351\230\265II.md"
+++ "b/problems/0059.\350\236\272\346\227\213\347\237\251\351\230\265II.md"
@@ -148,8 +148,6 @@ class Solution {
// 定义中间位置
int mid = n / 2;
-
-
while (loop > 0) {
int i = startX;
int j = startY;
@@ -182,7 +180,6 @@ class Solution {
offset += 2;
}
-
if (n % 2 == 1) {
res[mid][mid] = count;
}
diff --git "a/problems/0102.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\345\272\217\351\201\215\345\216\206.md" "b/problems/0102.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\345\272\217\351\201\215\345\216\206.md"
index b13fdd8df5..8be3ac47f2 100644
--- "a/problems/0102.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\345\272\217\351\201\215\345\216\206.md"
+++ "b/problems/0102.\344\272\214\345\217\211\346\240\221\347\232\204\345\261\202\345\272\217\351\201\215\345\216\206.md"
@@ -34,9 +34,10 @@
我们之前讲过了三篇关于二叉树的深度优先遍历的文章:
-* [二叉树:前中后序递归法](https://mp.weixin.qq.com/s/PwVIfxDlT3kRgMASWAMGhA)
-* [二叉树:前中后序迭代法](https://mp.weixin.qq.com/s/c_zCrGHIVlBjUH_hJtghCg)
-* [二叉树:前中后序迭代方式统一写法](https://mp.weixin.qq.com/s/WKg0Ty1_3SZkztpHubZPRg)
+* [二叉树:前中后序递归法](https://mp.weixin.qq.com/s/Ww60X5mIKWdMQV4cN3ejOA)
+* [二叉树:前中后序迭代法](https://mp.weixin.qq.com/s/OH7aCVJ5-Gi32PkNCoZk4A)
+* [二叉树:前中后序迭代方式统一写法](https://mp.weixin.qq.com/s/ATQMPCpBlaAgrqdLDMVPZA)
+
接下来我们再来介绍二叉树的另一种遍历方式:层序遍历。
diff --git "a/problems/0129.\346\261\202\346\240\271\345\210\260\345\217\266\345\255\220\350\212\202\347\202\271\346\225\260\345\255\227\344\271\213\345\222\214.md" "b/problems/0129.\346\261\202\346\240\271\345\210\260\345\217\266\345\255\220\350\212\202\347\202\271\346\225\260\345\255\227\344\271\213\345\222\214.md"
new file mode 100644
index 0000000000..a54ebf5919
--- /dev/null
+++ "b/problems/0129.\346\261\202\346\240\271\345\210\260\345\217\266\345\255\220\350\212\202\347\202\271\346\225\260\345\255\227\344\271\213\345\222\214.md"
@@ -0,0 +1,179 @@
+
+## 链接
+https://leetcode-cn.com/problems/sum-root-to-leaf-numbers/
+
+## 思路
+
+本题和[113.路径总和II](https://github.com/youngyangyang04/leetcode-master/blob/master/problems/0113.%E8%B7%AF%E5%BE%84%E6%80%BB%E5%92%8CII.md)是类似的思路,做完这道题,可以顺便把[113.路径总和II](https://github.com/youngyangyang04/leetcode-master/blob/master/problems/0113.%E8%B7%AF%E5%BE%84%E6%80%BB%E5%92%8CII.md) 和 [112.路径总和](https://github.com/youngyangyang04/leetcode/blob/master/problems/0112.路径总和.md) 做了。
+
+结合112.路径总和 和 113.路径总和II,我在讲了[二叉树:递归函数究竟什么时候需要返回值,什么时候不要返回值?](https://mp.weixin.qq.com/s/6TWAVjxQ34kVqROWgcRFOg),如果大家对二叉树递归函数什么时候需要返回值很迷茫,可以看一下。
+
+接下来在看本题,就简单多了,本题其实需要使用回溯,但一些同学可能都不知道自己用了回溯,在[二叉树:以为使用了递归,其实还隐藏着回溯](https://mp.weixin.qq.com/s/ivLkHzWdhjQQD1rQWe6zWA)中,我详细讲解了二叉树的递归中,如何使用了回溯。
+
+接下来我们来看题:
+
+首先思路很明确,就是要遍历整个树把更节点到叶子节点组成的数字相加。
+
+那么先按递归三部曲来分析:
+
+### 递归三部曲
+
+如果对递归三部曲不了解的话,可以看这里:[二叉树:前中后递归详解](https://mp.weixin.qq.com/s/PwVIfxDlT3kRgMASWAMGhA)
+
+* 确定递归函数返回值及其参数
+
+这里我们要遍历整个二叉树,且需要要返回值做逻辑处理,所有返回值为void,在[二叉树:递归函数究竟什么时候需要返回值,什么时候不要返回值?](https://mp.weixin.qq.com/s/6TWAVjxQ34kVqROWgcRFOg)中,详细讲解了返回值问题。
+
+参数只需要把根节点传入,此时还需要定义两个全局遍历,一个是result,记录最终结果,一个是vector path。
+
+**为什么用vector类型(就是数组)呢? 因为用vector方便我们做回溯!**
+
+所以代码如下:
+
+```
+int result;
+vector path;
+void traversal(TreeNode* cur)
+```
+
+* 确定终止条件
+
+递归什么时候终止呢?
+
+当然是遇到叶子节点,此时要收集结果了,通知返回本层递归,因为单条路径的结果使用vector,我们需要一个函数vectorToInt把vector转成int。
+
+终止条件代码如下:
+
+```
+if (!cur->left && !cur->right) { // 遇到了叶子节点
+ result += vectorToInt(path);
+ return;
+}
+```
+
+这里vectorToInt函数就是把数组转成int,代码如下:
+
+```C++
+int vectorToInt(const vector& vec) {
+ int sum = 0;
+ for (int i = 0; i < vec.size(); i++) {
+ sum = sum * 10 + vec[i];
+ }
+ return sum;
+}
+```
+
+
+* 确定递归单层逻辑
+
+本题其实采用前中后序都不无所谓, 因为也没有中间几点的处理逻辑。
+
+这里主要是当左节点不为空,path收集路径,并递归左孩子,右节点同理。
+
+**但别忘了回溯**。
+
+如图:
+
+
+
+
+代码如下:
+
+```C++
+ // 中
+if (cur->left) { // 左 (空节点不遍历)
+ path.push_back(cur->left->val);
+ traversal(cur->left); // 递归
+ path.pop_back(); // 回溯
+}
+if (cur->right) { // 右 (空节点不遍历)
+ path.push_back(cur->right->val);
+ traversal(cur->right); // 递归
+ path.pop_back(); // 回溯
+}
+```
+
+这里要注意回溯和递归要永远在一起,一个递归,对应一个回溯,是一对一的关系,有的同学写成如下代码:
+
+```C++
+if (cur->left) { // 左 (空节点不遍历)
+ path.push_back(cur->left->val);
+ traversal(cur->left); // 递归
+}
+if (cur->right) { // 右 (空节点不遍历)
+ path.push_back(cur->right->val);
+ traversal(cur->right); // 递归
+}
+path.pop_back(); // 回溯
+```
+**把回溯放在花括号外面了,世界上最遥远的距离,是你在花括号里,而我在花括号外!** 这就不对了。
+
+### 整体C++代码
+
+关键逻辑分析完了,整体C++代码如下:
+
+```C++
+class Solution {
+private:
+ int result;
+ vector path;
+ // 把vector转化为int
+ int vectorToInt(const vector& vec) {
+ int sum = 0;
+ for (int i = 0; i < vec.size(); i++) {
+ sum = sum * 10 + vec[i];
+ }
+ return sum;
+ }
+ void traversal(TreeNode* cur) {
+ if (!cur->left && !cur->right) { // 遇到了叶子节点
+ result += vectorToInt(path);
+ return;
+ }
+
+ if (cur->left) { // 左 (空节点不遍历)
+ path.push_back(cur->left->val); // 处理节点
+ traversal(cur->left); // 递归
+ path.pop_back(); // 回溯,撤销
+ }
+ if (cur->right) { // 右 (空节点不遍历)
+ path.push_back(cur->right->val); // 处理节点
+ traversal(cur->right); // 递归
+ path.pop_back(); // 回溯,撤销
+ }
+ return ;
+ }
+public:
+ int sumNumbers(TreeNode* root) {
+ path.clear();
+ if (root == nullptr) return 0;
+ path.push_back(root->val);
+ traversal(root);
+ return result;
+ }
+};
+```
+
+## 总结
+
+过于简洁的代码,很容易让初学者忽视了本题中回溯的精髓,甚至作者本身都没有想清楚自己用了回溯。
+
+**我这里提供的代码把整个回溯过程充分体现出来,希望可以帮助大家看的明明白白!**
+
+## 其他语言版本
+
+Java:
+
+Python:
+
+Go:
+
+JavaScript:
+
+
+
+-----------------------
+* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
+* B站视频:[代码随想录](https://space.bilibili.com/525438321)
+* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
+
diff --git "a/problems/0151.\347\277\273\350\275\254\345\255\227\347\254\246\344\270\262\351\207\214\347\232\204\345\215\225\350\257\215.md" "b/problems/0151.\347\277\273\350\275\254\345\255\227\347\254\246\344\270\262\351\207\214\347\232\204\345\215\225\350\257\215.md"
index ffa3446a5c..acdf84fc32 100644
--- "a/problems/0151.\347\277\273\350\275\254\345\255\227\347\254\246\344\270\262\351\207\214\347\232\204\345\215\225\350\257\215.md"
+++ "b/problems/0151.\347\277\273\350\275\254\345\255\227\347\254\246\344\270\262\351\207\214\347\232\204\345\215\225\350\257\215.md"
@@ -300,8 +300,9 @@ class Solution {
}
```
+python:
-```Python3
+```Python
class Solution:
#1.去除多余的空格
def trim_spaces(self,s):
@@ -349,7 +350,7 @@ class Solution:
return ''.join(l) #输出:blue is sky the
-'''
+```
Go:
diff --git "a/problems/0225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.md" "b/problems/0225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.md"
index 85b981e516..bcf82b84b8 100644
--- "a/problems/0225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.md"
+++ "b/problems/0225.\347\224\250\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.md"
@@ -200,14 +200,6 @@ class MyStack {
}
}
-/**
- * Your MyQueue object will be instantiated and called as such:
- * MyQueue obj = new MyQueue();
- * obj.push(x);
- * int param_2 = obj.pop();
- * int param_3 = obj.peek();
- * boolean param_4 = obj.empty();
- */
```
使用两个 Deque 实现
```java
@@ -350,12 +342,6 @@ class MyStack:
return False
-# Your MyStack object will be instantiated and called as such:
-# obj = MyStack()
-# obj.push(x)
-# param_2 = obj.pop()
-# param_3 = obj.top()
-# param_4 = obj.empty()
```
Go:
diff --git "a/problems/0226.\347\277\273\350\275\254\344\272\214\345\217\211\346\240\221.md" "b/problems/0226.\347\277\273\350\275\254\344\272\214\345\217\211\346\240\221.md"
index bb0d6d34ca..bba34766ff 100644
--- "a/problems/0226.\347\277\273\350\275\254\344\272\214\345\217\211\346\240\221.md"
+++ "b/problems/0226.\347\277\273\350\275\254\344\272\214\345\217\211\346\240\221.md"
@@ -7,7 +7,7 @@
欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!
-## 226.翻转二叉树
+# 226.翻转二叉树
题目地址:https://leetcode-cn.com/problems/invert-binary-tree/
@@ -17,7 +17,7 @@
这道题目背后有一个让程序员心酸的故事,听说 Homebrew的作者Max Howell,就是因为没在白板上写出翻转二叉树,最后被Google拒绝了。(真假不做判断,权当一个乐子哈)
-## 题外话
+# 题外话
这道题目是非常经典的题目,也是比较简单的题目(至少一看就会)。
@@ -25,7 +25,7 @@
如果做过这道题的同学也建议认真看完,相信一定有所收获!
-## 思路
+# 思路
我们之前介绍的都是各种方式遍历二叉树,这次要翻转了,感觉还是有点懵逼。
@@ -49,7 +49,9 @@
## 递归法
-对于二叉树的递归法的前中后序遍历,已经在[二叉树:前中后序递归遍历](https://mp.weixin.qq.com/s/PwVIfxDlT3kRgMASWAMGhA)详细讲解了。
+
+
+对于二叉树的递归法的前中后序遍历,已经在[二叉树:前中后序递归遍历](https://mp.weixin.qq.com/s/Ww60X5mIKWdMQV4cN3ejOA)详细讲解了。
我们下文以前序遍历为例,通过动画来看一下翻转的过程:
@@ -104,7 +106,8 @@ public:
### 深度优先遍历
-[二叉树:听说递归能做的,栈也能做!](https://mp.weixin.qq.com/s/c_zCrGHIVlBjUH_hJtghCg)中给出了前中后序迭代方式的写法,所以本地可以很轻松的切出如下迭代法的代码:
+
+[二叉树:听说递归能做的,栈也能做!](https://mp.weixin.qq.com/s/OH7aCVJ5-Gi32PkNCoZk4A)中给出了前中后序迭代方式的写法,所以本地可以很轻松的切出如下迭代法的代码:
C++代码迭代法(前序遍历)
@@ -126,10 +129,10 @@ public:
}
};
```
-如果这个代码看不懂的话可以在回顾一下[二叉树:听说递归能做的,栈也能做!](https://mp.weixin.qq.com/s/c_zCrGHIVlBjUH_hJtghCg)。
+如果这个代码看不懂的话可以在回顾一下[二叉树:听说递归能做的,栈也能做!](https://mp.weixin.qq.com/s/OH7aCVJ5-Gi32PkNCoZk4A)。
-我们在[二叉树:前中后序迭代方式的统一写法](https://mp.weixin.qq.com/s/WKg0Ty1_3SZkztpHubZPRg)中介绍了统一的写法,所以,本题也只需将文中的代码少做修改便可。
+我们在[二叉树:前中后序迭代方式的统一写法](https://mp.weixin.qq.com/s/ATQMPCpBlaAgrqdLDMVPZA)中介绍了统一的写法,所以,本题也只需将文中的代码少做修改便可。
C++代码如下迭代法(前序遍历)
@@ -159,7 +162,7 @@ public:
};
```
-如果上面这个代码看不懂,回顾一下文章[二叉树:前中后序迭代方式的统一写法](https://mp.weixin.qq.com/s/WKg0Ty1_3SZkztpHubZPRg)。
+如果上面这个代码看不懂,回顾一下文章[二叉树:前中后序迭代方式的统一写法](https://mp.weixin.qq.com/s/ATQMPCpBlaAgrqdLDMVPZA)。
### 广度优先遍历
@@ -185,7 +188,7 @@ public:
}
};
```
-如果对以上代码不理解,或者不清楚二叉树的层序遍历,可以看这篇[二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/Gb3BjakIKGNpup2jYtTzog)
+如果对以上代码不理解,或者不清楚二叉树的层序遍历,可以看这篇[二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/4-bDKi7SdwfBGRm9FYduiA)
## 总结
@@ -202,7 +205,7 @@ public:
## 其他语言版本
-Java:
+### Java:
```Java
//DFS递归
@@ -254,9 +257,9 @@ class Solution {
}
```
-Python:
+### Python
-> 递归法:前序遍历
+递归法:前序遍历:
```python
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
@@ -268,7 +271,7 @@ class Solution:
return root
```
-> 迭代法:深度优先遍历(前序遍历)
+迭代法:深度优先遍历(前序遍历):
```python
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
@@ -286,7 +289,7 @@ class Solution:
return root
```
-> 迭代法:广度优先遍历(层序遍历)
+迭代法:广度优先遍历(层序遍历):
```python
import collections
class Solution:
@@ -306,7 +309,8 @@ class Solution:
return root
```
-Go:
+### Go
+
```Go
func invertTree(root *TreeNode) *TreeNode {
if root ==nil{
@@ -323,7 +327,7 @@ func invertTree(root *TreeNode) *TreeNode {
}
```
-JavaScript:
+### JavaScript
使用递归版本的前序遍历
```javascript
diff --git "a/problems/0232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227.md" "b/problems/0232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227.md"
index be6e1df6fb..6890fc2bde 100644
--- "a/problems/0232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227.md"
+++ "b/problems/0232.\347\224\250\346\240\210\345\256\236\347\216\260\351\230\237\345\210\227.md"
@@ -385,15 +385,6 @@ func (this *MyQueue) Empty() bool {
return len(this.stack) == 0 && len(this.back) == 0
}
-/**
- * Your MyQueue object will be instantiated and called as such:
- * obj := Constructor();
- * obj.Push(x);
- * param_2 := obj.Pop();
- * param_3 := obj.Peek();
- * param_4 := obj.Empty();
- */
- ```
javaScript:
diff --git "a/problems/0459.\351\207\215\345\244\215\347\232\204\345\255\220\345\255\227\347\254\246\344\270\262.md" "b/problems/0459.\351\207\215\345\244\215\347\232\204\345\255\220\345\255\227\347\254\246\344\270\262.md"
index 368489a5e2..f012811d3d 100644
--- "a/problems/0459.\351\207\215\345\244\215\347\232\204\345\255\220\345\255\227\347\254\246\344\270\262.md"
+++ "b/problems/0459.\351\207\215\345\244\215\347\232\204\345\255\220\345\255\227\347\254\246\344\270\262.md"
@@ -37,7 +37,7 @@ https://leetcode-cn.com/problems/repeated-substring-pattern/
如果KMP还不够了解,可以看我的B站:
-* [帮你把KMP算法学个通透!B站(理论篇)](https://www.bilibili.com/video/BV1PD4y1o7nd/)
+* [帮你把KMP算法学个通透!(理论篇)](https://www.bilibili.com/video/BV1PD4y1o7nd/)
* [帮你把KMP算法学个通透!(求next数组代码篇)](https://www.bilibili.com/video/BV1M5411j7Xx)
diff --git "a/problems/0463.\345\262\233\345\261\277\347\232\204\345\221\250\351\225\277.md" "b/problems/0463.\345\262\233\345\261\277\347\232\204\345\221\250\351\225\277.md"
new file mode 100644
index 0000000000..403788547c
--- /dev/null
+++ "b/problems/0463.\345\262\233\345\261\277\347\232\204\345\221\250\351\225\277.md"
@@ -0,0 +1,98 @@
+
+## 题目链接
+https://leetcode-cn.com/problems/island-perimeter/
+
+## 思路
+
+岛屿问题最容易让人想到BFS或者DFS,但是这道题还真的没有必要,别把简单问题搞复杂了。
+
+### 解法一:
+
+遍历每一个空格,遇到岛屿,计算其上下左右的情况,遇到水域或者出界的情况,就可以计算边了。
+
+如图:
+
+
+
+C++代码如下:(详细注释)
+
+```C++
+class Solution {
+public:
+ int direction[4][2] = {0, 1, 1, 0, -1, 0, 0, -1};
+ int islandPerimeter(vector>& grid) {
+ int result = 0;
+ for (int i = 0; i < grid.size(); i++) {
+ for (int j = 0; j < grid[0].size(); j++) {
+ if (grid[i][j] == 1) {
+ for (int k = 0; k < 4; k++) { // 上下左右四个方向
+ int x = i + direction[k][0];
+ int y = j + direction[k][1]; // 计算周边坐标x,y
+ if (x < 0 // i在边界上
+ || x >= grid.size() // i在边界上
+ || y < 0 // j在边界上
+ || y >= grid[0].size() // j在边界上
+ || grid[x][y] == 0) { // x,y位置是水域
+ result++;
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+};
+```
+
+### 解法二:
+
+计算出总的岛屿数量,因为有一对相邻两个陆地,边的总数就减2,那么在计算出相邻岛屿的数量就可以了。
+
+result = 岛屿数量 * 4 - cover * 2;
+
+如图:
+
+
+
+C++代码如下:(详细注释)
+
+```C++
+class Solution {
+public:
+ int islandPerimeter(vector>& grid) {
+ int sum = 0; // 陆地数量
+ int cover = 0; // 相邻数量
+ for (int i = 0; i < grid.size(); i++) {
+ for (int j = 0; j < grid[0].size(); j++) {
+ if (grid[i][j] == 1) {
+ sum++;
+ // 统计上边相邻陆地
+ if(i - 1 >= 0 && grid[i - 1][j] == 1) cover++;
+ // 统计左边相邻陆地
+ if(j - 1 >= 0 && grid[i][j - 1] == 1) cover++;
+ // 为什么没统计下边和右边? 因为避免重复计算
+ }
+ }
+ }
+ return sum * 4 - cover * 2;
+ }
+};
+```
+
+
+## 其他语言版本
+
+Java:
+
+Python:
+
+Go:
+
+JavaScript:
+
+
+-----------------------
+* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
+* B站视频:[代码随想录](https://space.bilibili.com/525438321)
+* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
+
diff --git "a/problems/0704.\344\272\214\345\210\206\346\237\245\346\211\276.md" "b/problems/0704.\344\272\214\345\210\206\346\237\245\346\211\276.md"
index 931e6e5cea..cce471ae32 100644
--- "a/problems/0704.\344\272\214\345\210\206\346\237\245\346\211\276.md"
+++ "b/problems/0704.\344\272\214\345\210\206\346\237\245\346\211\276.md"
@@ -139,7 +139,7 @@ public:
## 相关题目推荐
-* [35.搜索插入位置](https://mp.weixin.qq.com/s/fCf5QbPDtE6SSlZ1yh_q8Q)
+* [35.搜索插入位置](./0035.搜索插入位置.md)
* 34.在排序数组中查找元素的第一个和最后一个位置
* 69.x 的平方根
* 367.有效的完全平方数
diff --git "a/problems/0707.\350\256\276\350\256\241\351\223\276\350\241\250.md" "b/problems/0707.\350\256\276\350\256\241\351\223\276\350\241\250.md"
index b67a36eb7b..8be28f88bc 100644
--- "a/problems/0707.\350\256\276\350\256\241\351\223\276\350\241\250.md"
+++ "b/problems/0707.\350\256\276\350\256\241\351\223\276\350\241\250.md"
@@ -28,9 +28,9 @@ https://leetcode-cn.com/problems/design-linked-list/
# 思路
-如果对链表的基础知识还不太懂,可以看这篇文章:[关于链表,你该了解这些!](https://mp.weixin.qq.com/s/ntlZbEdKgnFQKZkSUAOSpQ)
+如果对链表的基础知识还不太懂,可以看这篇文章:[关于链表,你该了解这些!](https://mp.weixin.qq.com/s/fDGMmLrW7ZHlzkzlf_dZkw)
-如果对链表的虚拟头结点不清楚,可以看这篇文章:[链表:听说用虚拟头节点会方便很多?](https://mp.weixin.qq.com/s/slM1CH5Ew9XzK93YOQYSjA)
+如果对链表的虚拟头结点不清楚,可以看这篇文章:[链表:听说用虚拟头节点会方便很多?](https://mp.weixin.qq.com/s/L5aanfALdLEwVWGvyXPDqA)
删除链表节点:
![链表-删除节点](https://img-blog.csdnimg.cn/20200806195114541.png)
diff --git "a/problems/0941.\346\234\211\346\225\210\347\232\204\345\261\261\350\204\211\346\225\260\347\273\204.md" "b/problems/0941.\346\234\211\346\225\210\347\232\204\345\261\261\350\204\211\346\225\260\347\273\204.md"
new file mode 100644
index 0000000000..6dbc3da2f1
--- /dev/null
+++ "b/problems/0941.\346\234\211\346\225\210\347\232\204\345\261\261\350\204\211\346\225\260\347\273\204.md"
@@ -0,0 +1,43 @@
+
+## 题目链接
+
+https://leetcode-cn.com/problems/valid-mountain-array/
+
+## 思路
+
+判断是山峰,主要就是要严格的保存左边到中间,和右边到中间是递增的。
+
+这样可以使用两个指针,left和right,让其按照如下规则移动,如图:
+
+
+
+**注意这里还是有一些细节,例如如下两点:**
+
+* 因为left和right是数组下表,移动的过程中注意不要数组越界
+* 如果left或者right没有移动,说明是一个单调递增或者递减的数组,依然不是山峰
+
+C++代码如下:
+
+```
+class Solution {
+public:
+ bool validMountainArray(vector& A) {
+ if (A.size() < 3) return false;
+ int left = 0;
+ int right = A.size() - 1;
+
+ // 注意防止越界
+ while (left < A.size() - 1 && A[left] < A[left + 1]) left++;
+
+ // 注意防止越界
+ while (right > 0 && A[right] < A[right - 1]) right--;
+
+ // 如果left或者right都在起始位置,说明不是山峰
+ if (left == right && left != 0 && right != A.size() - 1) return true;
+ return false;
+ }
+};
+```
+如果想系统学一学双指针的话, 可以看一下这篇[双指针法:总结篇!](https://mp.weixin.qq.com/s/_p7grwjISfMh0U65uOyCjA)
+
+
diff --git "a/problems/1002.\346\237\245\346\211\276\345\270\270\347\224\250\345\255\227\347\254\246.md" "b/problems/1002.\346\237\245\346\211\276\345\270\270\347\224\250\345\255\227\347\254\246.md"
new file mode 100644
index 0000000000..875340c4b8
--- /dev/null
+++ "b/problems/1002.\346\237\245\346\211\276\345\270\270\347\224\250\345\255\227\347\254\246.md"
@@ -0,0 +1,177 @@
+
+
+
+
+
+
+
+欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!
+
+
+# 1002. 查找常用字符
+
+https://leetcode-cn.com/problems/find-common-characters/
+
+给定仅有小写字母组成的字符串数组 A,返回列表中的每个字符串中都显示的全部字符(包括重复字符)组成的列表。例如,如果一个字符在每个字符串中出现 3 次,但不是 4 次,则需要在最终答案中包含该字符 3 次。
+
+你可以按任意顺序返回答案。
+
+【示例一】
+输入:["bella","label","roller"]
+输出:["e","l","l"]
+
+【示例二】
+输入:["cool","lock","cook"]
+输出:["c","o"]
+
+
+# 思路
+
+这道题意一起就有点绕,不是那么容易懂,其实就是26个小写字符中有字符 在所有字符串里都出现的话,就输出,重复的也算。
+
+例如:
+
+输入:["ll","ll","ll"]
+输出:["l","l"]
+
+这道题目一眼看上去,就是用哈希法,**“小写字符”,“出现频率”, 这些关键字都是为哈希法量身定做的啊**
+
+首先可以想到的是暴力解法,一个字符串一个字符串去搜,时间复杂度是O(n^m),n是字符串长度,m是有几个字符串。
+
+可以看出这是指数级别的时间复杂度,非常高,而且代码实现也不容易,因为要统计 重复的字符,还要适当的替换或者去重。
+
+那我们还是哈希法吧。如果对哈希法不了解,可以看这篇:[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/RSUANESA_tkhKhYe3ZR8Jg)。
+
+如果对用数组来做哈希法不了解的话,可以看这篇:[把数组当做哈希表来用,很巧妙!](https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA)。
+
+了解了哈希法,理解了数组在哈希法中的应用之后,可以来看解题思路了。
+
+整体思路就是统计出搜索字符串里26个字符的出现的频率,然后取每个字符频率最小值,最后转成输出格式就可以了。
+
+如图:
+
+![1002.查找常用字符](https://code-thinking.cdn.bcebos.com/pics/1002.查找常用字符.png)
+
+先统计第一个字符串所有字符出现的次数,代码如下:
+
+```
+int hash[26] = {0}; // 用来统计所有字符串里字符出现的最小频率
+for (int i = 0; i < A[0].size(); i++) { // 用第一个字符串给hash初始化
+ hash[A[0][i] - 'a']++;
+}
+```
+
+接下来,把其他字符串里字符的出现次数也统计出来一次放在hashOtherStr中。
+
+然后hash 和 hashOtherStr 取最小值,这是本题关键所在,此时取最小值,就是 一个字符在所有字符串里出现的最小次数了。
+
+代码如下:
+
+```
+int hashOtherStr[26] = {0}; // 统计除第一个字符串外字符的出现频率
+for (int i = 1; i < A.size(); i++) {
+ memset(hashOtherStr, 0, 26 * sizeof(int));
+ for (int j = 0; j < A[i].size(); j++) {
+ hashOtherStr[A[i][j] - 'a']++;
+ }
+ // 这是关键所在
+ for (int k = 0; k < 26; k++) { // 更新hash,保证hash里统计26个字符在所有字符串里出现的最小次数
+ hash[k] = min(hash[k], hashOtherStr[k]);
+ }
+}
+```
+此时hash里统计着字符在所有字符串里出现的最小次数,那么把hash转正题目要求的输出格式就可以了。
+
+代码如下:
+
+```
+// 将hash统计的字符次数,转成输出形式
+for (int i = 0; i < 26; i++) {
+ while (hash[i] != 0) { // 注意这里是while,多个重复的字符
+ string s(1, i + 'a'); // char -> string
+ result.push_back(s);
+ hash[i]--;
+ }
+}
+```
+
+整体C++代码如下:
+
+```C++
+class Solution {
+public:
+ vector commonChars(vector& A) {
+ vector result;
+ if (A.size() == 0) return result;
+ int hash[26] = {0}; // 用来统计所有字符串里字符出现的最小频率
+ for (int i = 0; i < A[0].size(); i++) { // 用第一个字符串给hash初始化
+ hash[A[0][i] - 'a']++;
+ }
+
+ int hashOtherStr[26] = {0}; // 统计除第一个字符串外字符的出现频率
+ for (int i = 1; i < A.size(); i++) {
+ memset(hashOtherStr, 0, 26 * sizeof(int));
+ for (int j = 0; j < A[i].size(); j++) {
+ hashOtherStr[A[i][j] - 'a']++;
+ }
+ // 更新hash,保证hash里统计26个字符在所有字符串里出现的最小次数
+ for (int k = 0; k < 26; k++) {
+ hash[k] = min(hash[k], hashOtherStr[k]);
+ }
+ }
+ // 将hash统计的字符次数,转成输出形式
+ for (int i = 0; i < 26; i++) {
+ while (hash[i] != 0) { // 注意这里是while,多个重复的字符
+ string s(1, i + 'a'); // char -> string
+ result.push_back(s);
+ hash[i]--;
+ }
+ }
+
+ return result;
+ }
+};
+```
+
+## 其他语言版本
+
+Java:
+
+```Java
+class Solution {
+ public List commonChars(String[] A) {
+ List result = new ArrayList<>();
+ if (A.length == 0) return result;
+ int[] hash= new int[26]; // 用来统计所有字符串里字符出现的最小频率
+ for (int i = 0; i < A[0].length(); i++) { // 用第一个字符串给hash初始化
+ hash[A[0].charAt(i)- 'a']++;
+ }
+ // 统计除第一个字符串外字符的出现频率
+ for (int i = 1; i < A.length; i++) {
+ int[] hashOtherStr= new int[26];
+ for (int j = 0; j < A[i].length(); j++) {
+ hashOtherStr[A[i].charAt(j)- 'a']++;
+ }
+ // 更新hash,保证hash里统计26个字符在所有字符串里出现的最小次数
+ for (int k = 0; k < 26; k++) {
+ hash[k] = Math.min(hash[k], hashOtherStr[k]);
+ }
+ }
+ // 将hash统计的字符次数,转成输出形式
+ for (int i = 0; i < 26; i++) {
+ while (hash[i] != 0) { // 注意这里是while,多个重复的字符
+ char c= (char) (i+'a');
+ result.add(String.valueOf(c));
+ hash[i]--;
+ }
+ }
+ return result;
+ }
+}
+```
+
+-----------------------
+* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
+* B站视频:[代码随想录](https://space.bilibili.com/525438321)
+* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
+
diff --git "a/problems/1356.\346\240\271\346\215\256\346\225\260\345\255\227\344\272\214\350\277\233\345\210\266\344\270\2131\347\232\204\346\225\260\347\233\256\346\216\222\345\272\217.md" "b/problems/1356.\346\240\271\346\215\256\346\225\260\345\255\227\344\272\214\350\277\233\345\210\266\344\270\2131\347\232\204\346\225\260\347\233\256\346\216\222\345\272\217.md"
new file mode 100644
index 0000000000..e8aee05593
--- /dev/null
+++ "b/problems/1356.\346\240\271\346\215\256\346\225\260\345\255\227\344\272\214\350\277\233\345\210\266\344\270\2131\347\232\204\346\225\260\347\233\256\346\216\222\345\272\217.md"
@@ -0,0 +1,89 @@
+
+## 题目链接
+https://leetcode-cn.com/problems/sort-integers-by-the-number-of-1-bits/
+
+## 思路
+
+这道题其实是考察如何计算一个数的二进制中1的数量。
+
+我提供两种方法:
+
+* 方法一:
+
+朴实无华挨个计算1的数量,最多就是循环n的二进制位数,32位。
+
+```C++
+int bitCount(int n) {
+ int count = 0; // 计数器
+ while (n > 0) {
+ if((n & 1) == 1) count++; // 当前位是1,count++
+ n >>= 1 ; // n向右移位
+ }
+ return count;
+}
+```
+
+* 方法二
+
+这种方法,只循环n的二进制中1的个数次,比方法一高效的多
+
+```C++
+int bitCount(int n) {
+ int count = 0;
+ while (n) {
+ n &= (n - 1); // 清除最低位的1
+ count++;
+ }
+ return count;
+}
+```
+以计算12的二进制1的数量为例,如图所示:
+
+
+
+下面我就使用方法二,来做这道题目:
+
+## C++代码
+
+```C++
+class Solution {
+private:
+ static int bitCount(int n) { // 计算n的二进制中1的数量
+ int count = 0;
+ while(n) {
+ n &= (n -1); // 清除最低位的1
+ count++;
+ }
+ return count;
+ }
+ static bool cmp(int a, int b) {
+ int bitA = bitCount(a);
+ int bitB = bitCount(b);
+ if (bitA == bitB) return a < b; // 如果bit中1数量相同,比较数值大小
+ return bitA < bitB; // 否则比较bit中1数量大小
+ }
+public:
+ vector sortByBits(vector& arr) {
+ sort(arr.begin(), arr.end(), cmp);
+ return arr;
+ }
+};
+```
+
+## 其他语言版本
+
+Java:
+
+Python:
+
+Go:
+
+JavaScript:
+
+
+
+-----------------------
+* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
+* B站视频:[代码随想录](https://space.bilibili.com/525438321)
+* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
+
diff --git "a/problems/\344\272\214\345\217\211\346\240\221\347\232\204\347\273\237\344\270\200\350\277\255\344\273\243\346\263\225.md" "b/problems/\344\272\214\345\217\211\346\240\221\347\232\204\347\273\237\344\270\200\350\277\255\344\273\243\346\263\225.md"
index 533bdfe7ec..9e24fef6fd 100644
--- "a/problems/\344\272\214\345\217\211\346\240\221\347\232\204\347\273\237\344\270\200\350\277\255\344\273\243\346\263\225.md"
+++ "b/problems/\344\272\214\345\217\211\346\240\221\347\232\204\347\273\237\344\270\200\350\277\255\344\273\243\346\263\225.md"
@@ -12,9 +12,9 @@
> 统一写法是一种什么感觉
-此时我们在[二叉树:一入递归深似海,从此offer是路人](https://mp.weixin.qq.com/s/PwVIfxDlT3kRgMASWAMGhA)中用递归的方式,实现了二叉树前中后序的遍历。
+此时我们在[二叉树:一入递归深似海,从此offer是路人](https://mp.weixin.qq.com/s/Ww60X5mIKWdMQV4cN3ejOA)中用递归的方式,实现了二叉树前中后序的遍历。
-在[二叉树:听说递归能做的,栈也能做!](https://mp.weixin.qq.com/s/c_zCrGHIVlBjUH_hJtghCg)中用栈实现了二叉树前后中序的迭代遍历(非递归)。
+在[二叉树:听说递归能做的,栈也能做!](https://mp.weixin.qq.com/s/OH7aCVJ5-Gi32PkNCoZk4A)中用栈实现了二叉树前后中序的迭代遍历(非递归)。
之后我们发现**迭代法实现的先中后序,其实风格也不是那么统一,除了先序和后序,有关联,中序完全就是另一个风格了,一会用栈遍历,一会又用指针来遍历。**
@@ -24,7 +24,7 @@
**重头戏来了,接下来介绍一下统一写法。**
-我们以中序遍历为例,在[二叉树:听说递归能做的,栈也能做!](https://mp.weixin.qq.com/s/c_zCrGHIVlBjUH_hJtghCg)中提到说使用栈的话,**无法同时解决访问节点(遍历节点)和处理节点(将元素放进结果集)不一致的情况**。
+我们以中序遍历为例,在[二叉树:听说递归能做的,栈也能做!](https://mp.weixin.qq.com/s/OH7aCVJ5-Gi32PkNCoZk4A)中提到说使用栈的话,**无法同时解决访问节点(遍历节点)和处理节点(将元素放进结果集)不一致的情况**。
**那我们就将访问的节点放入栈中,把要处理的节点也放入栈中但是要做标记。**
@@ -149,14 +149,13 @@ public:
-## 其他语言版本
+# 其他语言版本
Java:
- 迭代法前序遍历代码如下:
- ```java
- class Solution {
-
+迭代法前序遍历代码如下:
+```java
+class Solution {
public List preorderTraversal(TreeNode root) {
List result = new LinkedList<>();
Stack st = new Stack<>();
@@ -180,39 +179,39 @@ Java:
return result;
}
}
+```
- ```
- 迭代法中序遍历代码如下:
- ```java
- class Solution {
- public List inorderTraversal(TreeNode root) {
- List result = new LinkedList<>();
- Stack st = new Stack<>();
- if (root != null) st.push(root);
- while (!st.empty()) {
- TreeNode node = st.peek();
- if (node != null) {
- st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
- if (node.right!=null) st.push(node.right); // 添加右节点(空节点不入栈)
- st.push(node); // 添加中节点
- st.push(null); // 中节点访问过,但是还没有处理,加入空节点做为标记。
-
- if (node.left!=null) st.push(node.left); // 添加左节点(空节点不入栈)
- } else { // 只有遇到空节点的时候,才将下一个节点放进结果集
- st.pop(); // 将空节点弹出
- node = st.peek(); // 重新取出栈中元素
- st.pop();
- result.add(node.val); // 加入到结果集
- }
+迭代法中序遍历代码如下:
+```java
+class Solution {
+public List inorderTraversal(TreeNode root) {
+ List result = new LinkedList<>();
+ Stack st = new Stack<>();
+ if (root != null) st.push(root);
+ while (!st.empty()) {
+ TreeNode node = st.peek();
+ if (node != null) {
+ st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
+ if (node.right!=null) st.push(node.right); // 添加右节点(空节点不入栈)
+ st.push(node); // 添加中节点
+ st.push(null); // 中节点访问过,但是还没有处理,加入空节点做为标记。
+
+ if (node.left!=null) st.push(node.left); // 添加左节点(空节点不入栈)
+ } else { // 只有遇到空节点的时候,才将下一个节点放进结果集
+ st.pop(); // 将空节点弹出
+ node = st.peek(); // 重新取出栈中元素
+ st.pop();
+ result.add(node.val); // 加入到结果集
}
- return result;
}
+ return result;
+}
}
- ```
- 迭代法后序遍历代码如下:
- ```java
- class Solution {
+```
+迭代法后序遍历代码如下:
+```java
+class Solution {
public List postorderTraversal(TreeNode root) {
List result = new LinkedList<>();
Stack st = new Stack<>();
@@ -236,11 +235,11 @@ Java:
return result;
}
}
+```
- ```
Python:
-> 迭代法前序遍历
+迭代法前序遍历:
```python
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
@@ -263,7 +262,7 @@ class Solution:
return result
```
-> 迭代法中序遍历
+迭代法中序遍历:
```python
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
@@ -288,7 +287,7 @@ class Solution:
return result
```
-> 迭代法后序遍历
+迭代法后序遍历:
```python
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
diff --git "a/problems/\344\272\214\345\217\211\346\240\221\347\232\204\350\277\255\344\273\243\351\201\215\345\216\206.md" "b/problems/\344\272\214\345\217\211\346\240\221\347\232\204\350\277\255\344\273\243\351\201\215\345\216\206.md"
index 30b921ff4b..20397773e3 100644
--- "a/problems/\344\272\214\345\217\211\346\240\221\347\232\204\350\277\255\344\273\243\351\201\215\345\216\206.md"
+++ "b/problems/\344\272\214\345\217\211\346\240\221\347\232\204\350\277\255\344\273\243\351\201\215\345\216\206.md"
@@ -19,7 +19,7 @@
为什么可以用迭代法(非递归的方式)来实现二叉树的前后中序遍历呢?
-我们在[栈与队列:匹配问题都是栈的强项](https://mp.weixin.qq.com/s/eynAEbUbZoAWrk0ZlEugqg)中提到了,**递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中**,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。
+我们在[栈与队列:匹配问题都是栈的强项](https://mp.weixin.qq.com/s/1-x6r1wGA9mqIHW5LrMvBg)中提到了,**递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中**,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。
此时大家应该知道我们用栈也可以是实现二叉树的前后中序遍历了。
@@ -138,7 +138,7 @@ public:
```
-## 总结
+# 总结
此时我们用迭代法写出了二叉树的前后中序遍历,大家可以看出前序和中序是完全两种代码风格,并不想递归写法那样代码稍做调整,就可以实现前后中序。
@@ -153,7 +153,7 @@ public:
-## 其他语言版本
+# 其他语言版本
Java:
@@ -233,7 +233,8 @@ class Solution {
Python:
-```python3
+
+```python
# 前序遍历-迭代-LC144_二叉树的前序遍历
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
diff --git "a/problems/\345\211\215\345\272\217/\345\205\263\344\272\216\346\227\266\351\227\264\345\244\215\346\235\202\345\272\246\357\274\214\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\351\203\275\345\234\250\350\277\231\351\207\214\357\274\201.md" "b/problems/\345\211\215\345\272\217/\345\205\263\344\272\216\346\227\266\351\227\264\345\244\215\346\235\202\345\272\246\357\274\214\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\351\203\275\345\234\250\350\277\231\351\207\214\357\274\201.md"
index 4ca9eedeb1..d6471b9929 100644
--- "a/problems/\345\211\215\345\272\217/\345\205\263\344\272\216\346\227\266\351\227\264\345\244\215\346\235\202\345\272\246\357\274\214\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\351\203\275\345\234\250\350\277\231\351\207\214\357\274\201.md"
+++ "b/problems/\345\211\215\345\272\217/\345\205\263\344\272\216\346\227\266\351\227\264\345\244\215\346\235\202\345\272\246\357\274\214\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204\351\203\275\345\234\250\350\277\231\351\207\214\357\274\201.md"
@@ -7,12 +7,19 @@
欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!
+相信每一位录友都接触过时间复杂度,但又对时间复杂度的认识处于一种朦胧的状态,所以是时候对时间复杂度来一个深度的剖析了。
-Carl大胆断言:这可能是你见过对时间复杂度分析最通透的一篇文章了。
+本篇从如下六点进行分析:
-相信每一位录友都接触过时间复杂度,「代码随想录」已经也讲了一百多道经典题目了,是时候对时间复杂度来一个深度的剖析了,很早之前就写过一篇,当时文章还没有人看,Carl感觉有价值的东西值得让更多的人看到,哈哈。
+* 究竟什么是时间复杂度
+* 什么是大O
+* 不同数据规模的差异
+* 复杂表达式的化简
+* O(logn)中的log是以什么为底?
+* 举一个例子
-所以重新整理的时间复杂度文章,正式和大家见面啦!
+
+这可能是你见过对时间复杂度分析最通透的一篇文章。
## 究竟什么是时间复杂度
@@ -151,7 +158,7 @@ O(2 * n^2 + 10 * n + 1000) < O(3 * n^2),所以说最后省略掉常数项系
**当然这不是这道题目的最优解,我仅仅是用这道题目来讲解一下时间复杂度**。
-# 总结
+## 总结
本篇讲解了什么是时间复杂度,复杂度是用来干什么,以及数据规模对时间复杂度的影响。
@@ -161,12 +168,6 @@ O(2 * n^2 + 10 * n + 1000) < O(3 * n^2),所以说最后省略掉常数项系
相信看完本篇,大家对时间复杂度的认识会深刻很多!
-如果感觉「代码随想录」很不错,赶快推荐给身边的朋友同学们吧,他们发现和「代码随想录」相见恨晚!
-
-
-
-
-
-----------------------
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
diff --git "a/problems/\345\211\221\346\214\207Offer58-II.\345\267\246\346\227\213\350\275\254\345\255\227\347\254\246\344\270\262.md" "b/problems/\345\211\221\346\214\207Offer58-II.\345\267\246\346\227\213\350\275\254\345\255\227\347\254\246\344\270\262.md"
index 1701086e45..3c3eaef0a4 100644
--- "a/problems/\345\211\221\346\214\207Offer58-II.\345\267\246\346\227\213\350\275\254\345\255\227\347\254\246\344\270\262.md"
+++ "b/problems/\345\211\221\346\214\207Offer58-II.\345\267\246\346\227\213\350\275\254\345\255\227\347\254\246\344\270\262.md"
@@ -118,6 +118,8 @@ class Solution {
}
```
+python:
+
```python
# 方法一:可以使用切片方法
class Solution: