From 4fa39a5a47708e9a7cb13cf664acbbfc4a3d5a7b Mon Sep 17 00:00:00 2001
From: "ningwei.shi"
Date: Tue, 10 Nov 2020 15:32:02 +0800
Subject: [PATCH 01/12] =?UTF-8?q?=E6=8A=A2=E6=88=BF=E5=AD=90Python3?=
=?UTF-8?q?=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../\346\212\242\346\210\277\345\255\220.md" | 60 +++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\212\242\346\210\277\345\255\220.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\212\242\346\210\277\345\255\220.md"
index 8dae329bc6..ed5006086c 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\212\242\346\210\277\345\255\220.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\212\242\346\210\277\345\255\220.md"
@@ -259,3 +259,63 @@ int[] dp(TreeNode root) {
+[Shantom](https://github.com/Shantom) 提供 198. House Robber I Python3 解法代码:
+
+```Python
+class Solution:
+ def rob(self, nums: List[int]) -> int:
+ # 当前,上一间,上上间
+ cur, pre1, pre2 = 0, 0, 0
+
+ for num in nums:
+ # 当前 = max(上上间+(抢当前),上间(放弃当前))
+ cur = max(pre2 + num, pre1)
+ pre2 = pre1
+ pre1 = cur
+
+ return cur
+```
+[Shantom](https://github.com/Shantom) 提供 213. House Robber II Python3 解法代码:
+
+```Python
+class Solution:
+ def rob(self, nums: List[int]) -> int:
+ # 只有一间时不成环
+ if len(nums) == 1:
+ return nums[0]
+
+ # 该函数同198题
+ def subRob(nums: List[int]) -> int:
+ # 当前,上一间,上上间
+ cur, pre1, pre2 = 0, 0, 0
+ for num in nums:
+ # 当前 = max(上上间+(抢当前),上间(放弃当前))
+ cur = max(pre2 + num, pre1)
+ pre2 = pre1
+ pre1 = cur
+ return cur
+
+ # 不考虑第一间或者不考虑最后一间
+ return max(subRob(nums[:-1]), subRob(nums[1:]))
+```
+[Shantom](https://github.com/Shantom) 提供 337. House Robber III Python3 解法代码:
+
+```Python
+class Solution:
+ def rob(self, root: TreeNode) -> int:
+ # 返回值0项为不抢该节点,1项为抢该节点
+ def dp(root):
+ if not root:
+ return 0, 0
+
+ left = dp(root.left)
+ right = dp(root.right)
+
+ do = root.val + left[0] + right[0]
+ do_not = max(left) + max(right)
+
+ return do_not, do
+
+ return max(dp(root))
+```
+
From 97e5e1dee3df464f7deb181fba4139442d77ad26 Mon Sep 17 00:00:00 2001
From: hzs
Date: Wed, 11 Nov 2020 17:44:49 +0800
Subject: [PATCH 02/12] =?UTF-8?q?=E3=80=90877.=E7=9F=B3=E5=AD=90=E6=B8=B8?=
=?UTF-8?q?=E6=88=8F=E3=80=90Python=E3=80=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...32\345\274\210\351\227\256\351\242\230.md" | 55 ++++++++++++++++++-
1 file changed, 54 insertions(+), 1 deletion(-)
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\215\232\345\274\210\351\227\256\351\242\230.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\215\232\345\274\210\351\227\256\351\242\230.md"
index 9f52fa4929..c85c10008b 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\215\232\345\274\210\351\227\256\351\242\230.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\215\232\345\274\210\351\227\256\351\242\230.md"
@@ -215,4 +215,57 @@ int stoneGame(int[] piles) {
-======其他语言代码======
\ No newline at end of file
+======其他语言代码======
+
+
+
+
+
+python3版本
+
+由[SCUHZS](https://github.com/brucecat)提供
+
+这里采取的是三维的做法
+
+```python
+class Solution:
+ def stoneGame(self, piles: List[int]) -> bool:
+ n = len(piles)
+
+ # 初始化一个n*n的矩阵 dp数组
+ dp = [[None] * n for i in range(0, n)]
+
+ # 在三角区域填充
+ for i in range(n):
+ for j in range(i, n):
+ dp[i][j] = [0, 0]
+
+ # 填入base case
+ for i in range(0, n):
+ dp[i][i][0] = piles[i]
+ dp[i][i][1] = 0
+
+ # 斜着遍历数组
+ for l in range(2, n + 1):
+ for i in range(0, n-l+1):
+ j = l + i - 1
+
+
+ # 先手选择最左边或最右边的分数
+ left = piles[i] + dp[i + 1][j][1]
+ right = piles[j] + dp[i][j - 1][1]
+
+ # 套用状态转移方程
+ if left > right:
+ dp[i][j][0] = left
+ dp[i][j][1] = dp[i + 1][j][0]
+ else:
+ dp[i][j][0] = right
+ dp[i][j][1] = dp[i][j - 1][0]
+
+ res = dp[0][n - 1]
+
+ return res[0] - res[1] > 0
+
+```
+
From bc14b2e06201be75cf4a28b8d463e8e1f83f6608 Mon Sep 17 00:00:00 2001
From: hzs
Date: Wed, 11 Nov 2020 17:50:05 +0800
Subject: [PATCH 03/12] =?UTF-8?q?=E3=80=90877.=E7=9F=B3=E5=AD=90=E6=B8=B8?=
=?UTF-8?q?=E6=88=8F=E3=80=90Python=E3=80=91=E4=B8=80=E7=BB=B4dp?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...232\345\274\210\351\227\256\351\242\230.md" | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\215\232\345\274\210\351\227\256\351\242\230.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\215\232\345\274\210\351\227\256\351\242\230.md"
index c85c10008b..90615baf6b 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\215\232\345\274\210\351\227\256\351\242\230.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\215\232\345\274\210\351\227\256\351\242\230.md"
@@ -269,3 +269,21 @@ class Solution:
```
+
+
+压缩成一维数组,以减小空间复杂度,做法如下。
+
+```python
+class Solution:
+ def stoneGame(self, piles: List[int]) -> bool:
+ dp = piles.copy()
+
+ for i in range(len(piles) - 1, -1, -1): # 从下往上遍历
+ for j in range(i, len(piles)): # 从前往后遍历
+ dp[j] = max(piles[i] - dp[j], piles[j] - dp[j - 1]) # 计算之后覆盖一维数组的对应位置
+
+ return dp[len(piles) - 1] > 0
+
+
+```
+
From 36f59b6fe9ee832a7896e405c8bb76ae62b31e99 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BD=97=E5=B7=8D=E8=80=80-LWW?= <694125111@qq.com>
Date: Wed, 11 Nov 2020 22:27:58 +0800
Subject: [PATCH 04/12] =?UTF-8?q?Update=20=E6=89=93=E5=8D=B0=E7=B4=A0?=
=?UTF-8?q?=E6=95=B0.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
增加了C++版本的代码
---
...23\345\215\260\347\264\240\346\225\260.md" | 39 ++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
diff --git "a/\351\253\230\351\242\221\351\235\242\350\257\225\347\263\273\345\210\227/\346\211\223\345\215\260\347\264\240\346\225\260.md" "b/\351\253\230\351\242\221\351\235\242\350\257\225\347\263\273\345\210\227/\346\211\223\345\215\260\347\264\240\346\225\260.md"
index 2ab9e10af6..3a58074607 100644
--- "a/\351\253\230\351\242\221\351\235\242\350\257\225\347\263\273\345\210\227/\346\211\223\345\215\260\347\264\240\346\225\260.md"
+++ "b/\351\253\230\351\242\221\351\235\242\350\257\225\347\263\273\345\210\227/\346\211\223\345\215\260\347\264\240\346\225\260.md"
@@ -178,4 +178,41 @@ int countPrimes(int n) {
-======其他语言代码======
\ No newline at end of file
+======其他语言代码======
+
+C++解法:
+采用的算法是埃拉托斯特尼筛法
+埃拉托斯特尼筛法的具体内容就是:**要得到自然数n以内的全部素数,必须把不大于根号n的所有素数的倍数剔除,剩下的就是素数。**
+同时考虑到大于2的偶数都不是素数,所以可以进一步优化成:**要得到自然数n以内的全部素数,必须把不大于根号n的所有素数的奇数倍剔除,剩下的奇数就是素数。**
+此算法其实就是上面的Java解法所采用的。
+
+这里提供C++的代码:
+```C++
+class Solution {
+public:
+ int countPrimes(int n) {
+ int res = 0;
+ bool prime[n+1];
+ for(int i = 0; i < n; ++i)
+ prime[i] = true;
+
+ for(int i = 2; i <= sqrt(n); ++i) //计数过程
+ { //外循环优化,因为判断一个数是否为质数只需要整除到sqrt(n),反推亦然
+ if(prime[i])
+ {
+ for(int j = i * i; j < n; j += i) //内循环优化,i*i之前的比如i*2,i*3等,在之前的循环中已经验证了
+ {
+ prime[j] = false;
+ }
+ }
+ }
+ for (int i = 2; i < n; ++i)
+ if (prime[i]) res++; //最后遍历统计一遍,存入res
+
+ return res;
+ }
+};
+```
+
+
+
From 8a2f374f63d568d3e45d99a6c0c4466d399ea2d5 Mon Sep 17 00:00:00 2001
From: "ningwei.shi"
Date: Thu, 12 Nov 2020 09:21:54 +0800
Subject: [PATCH 05/12] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B3=A8=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../\346\212\242\346\210\277\345\255\220.md" | 2 ++
1 file changed, 2 insertions(+)
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\212\242\346\210\277\345\255\220.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\212\242\346\210\277\345\255\220.md"
index d2c3f0f7a6..081c583ac2 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\212\242\346\210\277\345\255\220.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\212\242\346\210\277\345\255\220.md"
@@ -311,7 +311,9 @@ class Solution:
left = dp(root.left)
right = dp(root.right)
+ # 抢当前,则两个下家不抢
do = root.val + left[0] + right[0]
+ # 不抢当前,则下家随意
do_not = max(left) + max(right)
return do_not, do
From 6294fbcb734ad5f79bfa10ef46610f2f7e19f4d1 Mon Sep 17 00:00:00 2001
From: labuladong
Date: Thu, 12 Nov 2020 14:26:22 +0800
Subject: [PATCH 06/12] fixurl
---
...345\215\232\345\274\210\351\227\256\351\242\230.md" | 2 +-
...345\242\236\345\255\220\345\272\217\345\210\227.md" | 10 +++++-----
...350\202\241\347\245\250\351\227\256\351\242\230.md" | 4 ++--
...344\274\230\345\255\220\347\273\223\346\236\204.md" | 2 +-
...351\270\241\350\233\213\351\227\256\351\242\230.md" | 2 +-
...347\252\227\345\217\243\346\212\200\345\267\247.md" | 4 ++--
6 files changed, 12 insertions(+), 12 deletions(-)
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\215\232\345\274\210\351\227\256\351\242\230.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\215\232\345\274\210\351\227\256\351\242\230.md"
index 90615baf6b..44246ab009 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\215\232\345\274\210\351\227\256\351\242\230.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\344\271\213\345\215\232\345\274\210\351\227\256\351\242\230.md"
@@ -22,7 +22,7 @@
上一篇文章 [几道智力题](https://labuladong.gitbook.io/algo) 中讨论到一个有趣的「石头游戏」,通过题目的限制条件,这个游戏是先手必胜的。但是智力题终究是智力题,真正的算法问题肯定不会是投机取巧能搞定的。所以,本文就借石头游戏来讲讲「假设两个人都足够聪明,最后谁会获胜」这一类问题该如何用动态规划算法解决。
-博弈类问题的套路都差不多,下文举例讲解,其核心思路是在二维 dp 的基础上使用元组分别存储两个人的博弈结果。掌握了这个技巧以后,别人再问你什么俩海盗分宝石,俩人拿硬币的问题,你就告诉别人:我懒得想,直接给你写个算法算一下得了。
+博弈类问题的套路都差不多,下文参考 [这个 YouTube 视频](https://www.youtube.com/watch?v=WxpIHvsu1RI) 的思路讲解,其核心思路是在二维 dp 的基础上使用元组分别存储两个人的博弈结果。掌握了这个技巧以后,别人再问你什么俩海盗分宝石,俩人拿硬币的问题,你就告诉别人:我懒得想,直接给你写个算法算一下得了。
我们「石头游戏」改的更具有一般性:
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\350\256\276\350\256\241\357\274\232\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\350\256\276\350\256\241\357\274\232\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.md"
index c905a6095e..4613f84d7b 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\350\256\276\350\256\241\357\274\232\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\350\256\276\350\256\241\357\274\232\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.md"
@@ -10,8 +10,8 @@
![](../pictures/souyisou.png)
相关推荐:
- * [动态规划设计:最大子数组](../动态规划系列/最大子数组.md)
- * [一文学会递归解题](../投稿/一文学会递归解题.md)
+ * [动态规划设计:最大子数组](https://labuladong.gitbook.io/algo)
+ * [一文学会递归解题](https://labuladong.gitbook.io/algo)
读完本文,你不仅学会了算法套路,还可以顺便去 LeetCode 上拿下如下题目:
@@ -19,7 +19,7 @@
**-----------**
-也许有读者看了前文 [动态规划详解](../动态规划系列/动态规划详解进阶.md),学会了动态规划的套路:找到了问题的「状态」,明确了 `dp` 数组/函数的含义,定义了 base case;但是不知道如何确定「选择」,也就是不到状态转移的关系,依然写不出动态规划解法,怎么办?
+也许有读者看了前文 [动态规划详解](https://labuladong.gitbook.io/algo),学会了动态规划的套路:找到了问题的「状态」,明确了 `dp` 数组/函数的含义,定义了 base case;但是不知道如何确定「选择」,也就是不到状态转移的关系,依然写不出动态规划解法,怎么办?
不要担心,动态规划的难点本来就在于寻找正确的状态转移方程,本文就借助经典的「最长递增子序列问题」来讲一讲设计动态规划的通用技巧:**数学归纳思想**。
@@ -43,7 +43,7 @@
**我们的定义是这样的:`dp[i]` 表示以 `nums[i]` 这个数结尾的最长递增子序列的长度。**
-PS:为什么这样定义呢?这是解决子序列问题的一个套路,后文[动态规划之子序列问题解题模板](../动态规划系列/子序列问题模板.md) 总结了几种常见套路。你读完本章所有的动态规划问题,就会发现 `dp` 数组的定义方法也就那几种。
+PS:为什么这样定义呢?这是解决子序列问题的一个套路,后文[动态规划之子序列问题解题模板](https://labuladong.gitbook.io/algo) 总结了几种常见套路。你读完本章所有的动态规划问题,就会发现 `dp` 数组的定义方法也就那几种。
根据这个定义,我们就可以推出 base case:`dp[i]` 初始值为 1,因为以 `nums[i]` 结尾的最长递增子序列起码要包含它自己。
@@ -164,7 +164,7 @@ public int lengthOfLIS(int[] nums) {
我们只要把处理扑克牌的过程编程写出来即可。每次处理一张扑克牌不是要找一个合适的牌堆顶来放吗,牌堆顶的牌不是**有序**吗,这就能用到二分查找了:用二分查找来搜索当前牌应放置的位置。
-PS:旧文[二分查找算法详解](../算法思维系列/二分查找详解.md)详细介绍了二分查找的细节及变体,这里就完美应用上了,如果没读过强烈建议阅读。
+PS:旧文[二分查找算法详解](https://labuladong.gitbook.io/algo)详细介绍了二分查找的细节及变体,这里就完美应用上了,如果没读过强烈建议阅读。
```java
public int lengthOfLIS(int[] nums) {
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\233\242\347\201\255\350\202\241\347\245\250\351\227\256\351\242\230.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\233\242\347\201\255\350\202\241\347\245\250\351\227\256\351\242\230.md"
index be2b463814..61f64a36a5 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\233\242\347\201\255\350\202\241\347\245\250\351\227\256\351\242\230.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\233\242\347\201\255\350\202\241\347\245\250\351\227\256\351\242\230.md"
@@ -16,7 +16,7 @@
读完本文,你不仅学会了算法套路,还可以顺便去 LeetCode 上拿下如下题目:
-[买卖股票的最佳时机](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/solution/)
+[买卖股票的最佳时机](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock)
[买卖股票的最佳时机 II](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/)
@@ -32,7 +32,7 @@
很多读者抱怨 LeetCode 的股票系列问题奇技淫巧太多,如果面试真的遇到这类问题,基本不会想到那些巧妙的办法,怎么办?**所以本文拒绝奇技淫巧,而是稳扎稳打,只用一种通用方法解决所用问题,以不变应万变**。
-这篇文章用状态机的技巧来解决,可以全部提交通过。不要觉得这个名词高大上,文学词汇而已,实际上就是 DP table,看一眼就明白了。
+这篇文章参考 [英文版高赞题解](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/discuss/108870/Most-consistent-ways-of-dealing-with-the-series-of-stock-problems) 的思路,用状态机的技巧来解决,可以全部提交通过。不要觉得这个名词高大上,文学词汇而已,实际上就是 DP table,看一眼就明白了。
先随便抽出一道题,看看别人的解法:
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\234\200\344\274\230\345\255\220\347\273\223\346\236\204.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\234\200\344\274\230\345\255\220\347\273\223\346\236\204.md"
index 2dc21f2275..caf68cfe98 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\234\200\344\274\230\345\255\220\347\273\223\346\236\204.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\234\200\344\274\230\345\255\220\347\273\223\346\236\204.md"
@@ -54,7 +54,7 @@ return result;
当然,上面这个例子太简单了,不过请读者回顾一下,我们做动态规划问题,是不是一直在求各种最值,本质跟我们举的例子没啥区别,无非需要处理一下重叠子问题。
-前文不[同定义不同解法](../动态规划系列/动态规划之四键键盘.md) 和 [高楼扔鸡蛋进阶](../动态规划系列/高楼扔鸡蛋问题.md) 就展示了如何改造问题,不同的最优子结构,可能导致不同的解法和效率。
+前文不[同定义不同解法](https://labuladong.gitbook.io/algo) 和 [高楼扔鸡蛋进阶](https://labuladong.gitbook.io/algo) 就展示了如何改造问题,不同的最优子结构,可能导致不同的解法和效率。
再举个常见但也十分简单的例子,求一棵二叉树的最大值,不难吧(简单起见,假设节点中的值都是非负数):
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\351\253\230\346\245\274\346\211\224\351\270\241\350\233\213\351\227\256\351\242\230.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\351\253\230\346\245\274\346\211\224\351\270\241\350\233\213\351\227\256\351\242\230.md"
index 70c63a01b7..68bd9b8655 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\351\253\230\346\245\274\346\211\224\351\270\241\350\233\213\351\227\256\351\242\230.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\351\253\230\346\245\274\346\211\224\351\270\241\350\233\213\351\227\256\351\242\230.md"
@@ -243,7 +243,7 @@ def superEggDrop(self, K: int, N: int) -> int:
return dp(K, N)
```
-这里就不展开其他解法了,留在下一篇文章 [高楼扔鸡蛋进阶](../动态规划系列/高楼扔鸡蛋进阶.md)
+这里就不展开其他解法了,留在下一篇文章 [高楼扔鸡蛋进阶](https://labuladong.gitbook.io/algo)
我觉得吧,我们这种解法就够了:找状态,做选择,足够清晰易懂,可流程化,可举一反三。掌握这套框架学有余力的话,再去考虑那些奇技淫巧也不迟。
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\347\263\273\345\210\227/\346\273\221\345\212\250\347\252\227\345\217\243\346\212\200\345\267\247.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\347\263\273\345\210\227/\346\273\221\345\212\250\347\252\227\345\217\243\346\212\200\345\267\247.md"
index e65a1041f5..67e6539ca1 100644
--- "a/\347\256\227\346\263\225\346\200\235\347\273\264\347\263\273\345\210\227/\346\273\221\345\212\250\347\252\227\345\217\243\346\212\200\345\267\247.md"
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\347\263\273\345\210\227/\346\273\221\345\212\250\347\252\227\345\217\243\346\212\200\345\267\247.md"
@@ -12,8 +12,8 @@
**最新消息:关注公众号参与活动,有机会成为 [70k star 算法仓库](https://github.com/labuladong/fucking-algorithm) 的贡献者,机不可失时不再来**!
相关推荐:
-* [东哥吃葡萄时竟然吃出一道算法题!](../高频面试系列/吃葡萄.md)
-* [如何寻找缺失的元素](../高频面试系列/消失的元素.md)
+* [东哥吃葡萄时竟然吃出一道算法题!](https://labuladong.gitbook.io/algo)
+* [如何寻找缺失的元素](https://labuladong.gitbook.io/algo)
读完本文,你不仅学会了算法套路,还可以顺便去 LeetCode 上拿下如下题目:
From 4591b795796a287b76cf340adc1e69d1c10066d2 Mon Sep 17 00:00:00 2001
From: HuangXiao
Date: Wed, 11 Nov 2020 11:51:34 +0800
Subject: [PATCH 07/12] Add java code for LCS
---
...61\345\255\220\345\272\217\345\210\227.md" | 27 ++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\234\200\351\225\277\345\205\254\345\205\261\345\255\220\345\272\217\345\210\227.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\234\200\351\225\277\345\205\254\345\205\261\345\255\220\345\272\217\345\210\227.md"
index bee894738b..39b13dd6de 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\234\200\351\225\277\345\205\254\345\205\261\345\255\220\345\272\217\345\210\227.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\346\234\200\351\225\277\345\205\254\345\205\261\345\255\220\345\272\217\345\210\227.md"
@@ -147,4 +147,29 @@ else:
-======其他语言代码======
\ No newline at end of file
+======其他语言代码======
+
+[Shawn](https://github.com/Shawn-Hx) 提供 Java 代码:
+
+```java
+public int longestCommonSubsequence(String text1, String text2) {
+ // 字符串转为char数组以加快访问速度
+ char[] str1 = text1.toCharArray();
+ char[] str2 = text2.toCharArray();
+
+ int m = str1.length, n = str2.length;
+ // 构建dp table,初始值默认为0
+ int[][] dp = new int[m + 1][n + 1];
+ // 状态转移
+ for (int i = 1; i <= m; i++)
+ for (int j = 1; j <= n; j++)
+ if (str1[i - 1] == str2[j - 1])
+ // 找到LCS中的字符
+ dp[i][j] = dp[i-1][j-1] + 1;
+ else
+ dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
+
+ return dp[m][n];
+}
+```
+
From 4d4a55f28ed891e8c98db8bb593ae54acf6d33cf Mon Sep 17 00:00:00 2001
From: Kian Kwok
Date: Wed, 11 Nov 2020 11:37:25 +0800
Subject: [PATCH 08/12] =?UTF-8?q?Update=20=E5=8A=A8=E6=80=81=E8=A7=84?=
=?UTF-8?q?=E5=88=92=E8=AE=BE=E8=AE=A1=EF=BC=9A=E6=9C=80=E9=95=BF=E9=80=92?=
=?UTF-8?q?=E5=A2=9E=E5=AD=90=E5=BA=8F=E5=88=97.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
create problem-300 c++
---
...36\345\255\220\345\272\217\345\210\227.md" | 43 ++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\350\256\276\350\256\241\357\274\232\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\350\256\276\350\256\241\357\274\232\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.md"
index 4613f84d7b..a2a04608ec 100644
--- "a/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\350\256\276\350\256\241\357\274\232\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.md"
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222\347\263\273\345\210\227/\345\212\250\346\200\201\350\247\204\345\210\222\350\256\276\350\256\241\357\274\232\346\234\200\351\225\277\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.md"
@@ -215,4 +215,45 @@ public int lengthOfLIS(int[] nums) {
-======其他语言代码======
\ No newline at end of file
+======其他语言代码======
+
+[Kian](https://github.com/KianKw/) 提供 C++ 代码
+
+```c++
+class Solution {
+public:
+ int lengthOfLIS(vector& nums) {
+ /* len 为牌的数量 */
+ int len = nums.size();
+ vector top(len, 0);
+ /* 牌堆数初始化为0 */
+ int piles = 0;
+ for (int i = 0; i < len; i++) {
+ /* nums[i] 为要处理的扑克牌 */
+ int poker = nums[i];
+
+ /***** 搜索左侧边界的二分查找 *****/
+ int left = 0, right = piles;
+ while (left < right) {
+ int mid = left + (right - left) / 2;
+ if (top[mid] > poker) {
+ right = mid;
+ } else if (top[mid] < poker) {
+ left = mid + 1;
+ } else if (top[mid] == poker) {
+ right = mid;
+ }
+ }
+ /*********************************/
+
+ /* 没找到合适的牌堆,新建一堆 */
+ if (left == piles)
+ piles++;
+ /* 把这张牌放到牌堆顶 */
+ top[left] = poker;
+ }
+ /* 牌堆数就是 LIS 长度 */
+ return piles;
+ }
+};
+```
From 8473c84f8d9207882efed9b45fdb5b1ac6153564 Mon Sep 17 00:00:00 2001
From: Lu Zhao
Date: Tue, 10 Nov 2020 20:00:07 -0800
Subject: [PATCH 09/12] add 20 java
---
...54\345\217\267\345\210\244\345\256\232.md" | 26 ++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git "a/\351\253\230\351\242\221\351\235\242\350\257\225\347\263\273\345\210\227/\345\220\210\346\263\225\346\213\254\345\217\267\345\210\244\345\256\232.md" "b/\351\253\230\351\242\221\351\235\242\350\257\225\347\263\273\345\210\227/\345\220\210\346\263\225\346\213\254\345\217\267\345\210\244\345\256\232.md"
index 32239bdae4..3bded5a322 100644
--- "a/\351\253\230\351\242\221\351\235\242\350\257\225\347\263\273\345\210\227/\345\220\210\346\263\225\346\213\254\345\217\267\345\210\244\345\256\232.md"
+++ "b/\351\253\230\351\242\221\351\235\242\350\257\225\347\263\273\345\210\227/\345\220\210\346\263\225\346\213\254\345\217\267\345\210\244\345\256\232.md"
@@ -112,4 +112,28 @@ char leftOf(char c) {
-======其他语言代码======
\ No newline at end of file
+======其他语言代码======
+
+```java
+//基本思想:每次遇到左括号时都将相对应的右括号')',']'或'}'推入堆栈
+//如果在字符串中出现右括号,则需要检查堆栈是否为空,以及顶部元素是否与该右括号相同。如果不是,则该字符串无效。
+//最后,我们还需要检查堆栈是否为空
+public boolean isValid(String s) {
+ Deque stack = new ArrayDeque<>();
+ for(char c : s.toCharArray()){
+ //是左括号就将相对应的右括号入栈
+ if(c=='(') {
+ stack.offerLast(')');
+ }else if(c=='{'){
+ stack.offerLast('}');
+ }else if(c=='['){
+ stack.offerLast(']');
+ }else if(stack.isEmpty() || stack.pollLast()!=c){//出现右括号,检查堆栈是否为空,以及顶部元素是否与该右括号相同
+ return false;
+ }
+ }
+ return stack.isEmpty();
+}
+
+```
+
From 780a1c46612684861613925295117ea7f85307b8 Mon Sep 17 00:00:00 2001
From: Ryan Deng
Date: Tue, 10 Nov 2020 22:58:31 -0500
Subject: [PATCH 10/12] =?UTF-8?q?=E3=80=90141.=E7=8E=AF=E5=BD=A2=E9=93=BE?=
=?UTF-8?q?=E8=A1=A8=E3=80=91=E3=80=90Python=E3=80=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...07\351\222\210\346\212\200\345\267\247.md" | 23 ++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\347\263\273\345\210\227/\345\217\214\346\214\207\351\222\210\346\212\200\345\267\247.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\347\263\273\345\210\227/\345\217\214\346\214\207\351\222\210\346\212\200\345\267\247.md"
index cf5227d184..f5edbd4268 100644
--- "a/\347\256\227\346\263\225\346\200\235\347\273\264\347\263\273\345\210\227/\345\217\214\346\214\207\351\222\210\346\212\200\345\267\247.md"
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\347\263\273\345\210\227/\345\217\214\346\214\207\351\222\210\346\212\200\345\267\247.md"
@@ -230,4 +230,25 @@ void reverse(int[] nums) {
-======其他语言代码======
\ No newline at end of file
+======其他语言代码======
+
+[ryandeng32](https://github.com/ryandeng32/) 提供 Python 代码
+```python
+class Solution:
+ def hasCycle(self, head: ListNode) -> bool:
+ # 检查链表头是否为None,是的话则不可能为环形
+ if head is None:
+ return False
+ # 快慢指针初始化
+ slow = fast = head
+ # 若链表非环形则快指针终究会遇到None,然后退出循环
+ while fast.next and fast.next.next:
+ # 更新快慢指针
+ slow = slow.next
+ fast = fast.next.next
+ # 快指针追上慢指针则链表为环形
+ if slow == fast:
+ return True
+ # 退出循环,则链表有结束,不可能为环形
+ return False
+```
From 513fac4f4b9a44a71159118be5df08fa59c56245 Mon Sep 17 00:00:00 2001
From: FrankHui <757583912@qq.com>
Date: Wed, 11 Nov 2020 12:54:40 +0800
Subject: [PATCH 11/12] =?UTF-8?q?=E3=80=90146.=20LRU=E7=BC=93=E5=AD=98?=
=?UTF-8?q?=E6=9C=BA=E5=88=B6=E3=80=91=E3=80=90=20python3=E3=80=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
python3版本的LRU缓存机制
---
.../LRU\347\256\227\346\263\225.md" | 32 ++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)
diff --git "a/\351\253\230\351\242\221\351\235\242\350\257\225\347\263\273\345\210\227/LRU\347\256\227\346\263\225.md" "b/\351\253\230\351\242\221\351\235\242\350\257\225\347\263\273\345\210\227/LRU\347\256\227\346\263\225.md"
index b9ca311c32..04ebea80fe 100644
--- "a/\351\253\230\351\242\221\351\235\242\350\257\225\347\263\273\345\210\227/LRU\347\256\227\346\263\225.md"
+++ "b/\351\253\230\351\242\221\351\235\242\350\257\225\347\263\273\345\210\227/LRU\347\256\227\346\263\225.md"
@@ -346,4 +346,34 @@ class LRUCache {
-======其他语言代码======
\ No newline at end of file
+======其他语言代码======
+```python3
+"""
+所谓LRU缓存,根本的难点在于记录最久被使用的键值对,这就设计到排序的问题,
+在python中,天生具备排序功能的字典就是OrderDict。
+注意到,记录最久未被使用的键值对的充要条件是将每一次put/get的键值对都定义为
+最近访问,那么最久未被使用的键值对自然就会排到最后。
+如果你深入python OrderDict的底层实现,就会知道它的本质是个双向链表+字典。
+它内置支持了
+1. move_to_end来重排链表顺序,它可以让我们将最近访问的键值对放到最后面
+2. popitem来弹出键值对,它既可以弹出最近的,也可以弹出最远的,弹出最远的就是我们要的操作。
+"""
+from collections import OrderedDict
+class LRUCache:
+ def __init__(self, capacity: int):
+ self.capacity = capacity # cache的容量
+ self.visited = OrderedDict() # python内置的OrderDict具备排序的功能
+ def get(self, key: int) -> int:
+ if key not in self.visited:
+ return -1
+ self.visited.move_to_end(key) # 最近访问的放到链表最后,维护好顺序
+ return self.visited[key]
+ def put(self, key: int, value: int) -> None:
+ if key not in self.visited and len(self.visited) == self.capacity:
+ # last=False时,按照FIFO顺序弹出键值对
+ # 因为我们将最近访问的放到最后,所以最远访问的就是最前的,也就是最first的,故要用FIFO顺序
+ self.visited.popitem(last=False)
+ self.visited[key]=value
+ self.visited.move_to_end(key) # 最近访问的放到链表最后,维护好顺序
+
+```
From 372b92bf7cd5bbbb00c96717806bed7f254da655 Mon Sep 17 00:00:00 2001
From: dekunma <53892579+dekunma@users.noreply.github.com>
Date: Wed, 11 Nov 2020 14:21:23 +0800
Subject: [PATCH 12/12] =?UTF-8?q?=E3=80=9098.=20=E9=AA=8C=E8=AF=81?=
=?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91=E3=80=91=E3=80=90?=
=?UTF-8?q?C++=E3=80=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...15\344\275\234\351\233\206\351\224\246.md" | 34 ++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\347\263\273\345\210\227/\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\346\223\215\344\275\234\351\233\206\351\224\246.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204\347\263\273\345\210\227/\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\346\223\215\344\275\234\351\233\206\351\224\246.md"
index 801b8fbc4a..b30ceebb9b 100644
--- "a/\346\225\260\346\215\256\347\273\223\346\236\204\347\263\273\345\210\227/\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\346\223\215\344\275\234\351\233\206\351\224\246.md"
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204\347\263\273\345\210\227/\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\346\223\215\344\275\234\351\233\206\351\224\246.md"
@@ -310,4 +310,36 @@ void BST(TreeNode root, int target) {
-======其他语言代码======
\ No newline at end of file
+======其他语言代码======
+[dekunma](https://www.linkedin.com/in/dekun-ma-036a9b198/)提供第98题C++代码:
+```C++
+/**
+ * Definition for a binary tree node.
+ * struct TreeNode {
+ * int val;
+ * TreeNode *left;
+ * TreeNode *right;
+ * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
+ * };
+ */
+class Solution {
+public:
+ bool isValidBST(TreeNode* root) {
+ // 用helper method求解
+ return isValidBST(root, nullptr, nullptr);
+ }
+
+ bool isValidBST(TreeNode* root, TreeNode* min, TreeNode* max) {
+ // base case, root为nullptr
+ if (!root) return true;
+
+ // 不符合BST的条件
+ if (min && root->val <= min->val) return false;
+ if (max && root->val >= max->val) return false;
+
+ // 向左右子树分别递归求解
+ return isValidBST(root->left, min, root)
+ && isValidBST(root->right, root, max);
+ }
+};
+```