+
长度为前2个字符的子串`aa`,最长相同前后缀的长度为1。
+
长度为前3个字符的子串`aab`,最长相同前后缀的长度为0。
以此类推:
diff --git a/problems/0072.编辑距离.md b/problems/0072.编辑距离.md
index a34439e6..8a877d20 100644
--- a/problems/0072.编辑距离.md
+++ b/problems/0072.编辑距离.md
@@ -20,24 +20,20 @@
* 输入:word1 = "horse", word2 = "ros"
* 输出:3
* 解释:
-```
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')
-``
* 示例 2:
* 输入:word1 = "intention", word2 = "execution"
* 输出:5
* 解释:
-```
intention -> inention (删除 't')
inention -> enention (将 'i' 替换为 'e')
enention -> exention (将 'n' 替换为 'x')
exention -> exection (将 'n' 替换为 'c')
exection -> execution (插入 'u')
-```
提示:
diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md
index 8ae7ee79..220232a2 100644
--- a/problems/0102.二叉树的层序遍历.md
+++ b/problems/0102.二叉树的层序遍历.md
@@ -2532,20 +2532,18 @@ class Solution:
return 0
queue_ = [root]
- result = []
+ depth = 0
while queue_:
length = len(queue_)
- sub = []
for i in range(length):
cur = queue_.pop(0)
sub.append(cur.val)
#子节点入队列
if cur.left: queue_.append(cur.left)
if cur.right: queue_.append(cur.right)
- result.append(sub)
+ depth += 1
-
- return len(result)
+ return depth
```
Go:
diff --git a/problems/0150.逆波兰表达式求值.md b/problems/0150.逆波兰表达式求值.md
index 176ea687..f0323bc4 100644
--- a/problems/0150.逆波兰表达式求值.md
+++ b/problems/0150.逆波兰表达式求值.md
@@ -163,6 +163,25 @@ class Solution {
python3
+```python
+from operator import add, sub, mul
+
+class Solution:
+ op_map = {'+': add, '-': sub, '*': mul, '/': lambda x, y: int(x / y)}
+
+ def evalRPN(self, tokens: List[str]) -> int:
+ stack = []
+ for token in tokens:
+ if token not in {'+', '-', '*', '/'}:
+ stack.append(int(token))
+ else:
+ op2 = stack.pop()
+ op1 = stack.pop()
+ stack.append(self.op_map[token](op1, op2)) # 第一个出来的在运算符后面
+ return stack.pop()
+```
+
+另一种可行,但因为使用eval相对较慢的方法:
```python
class Solution:
def evalRPN(self, tokens: List[str]) -> int:
diff --git a/problems/0222.完全二叉树的节点个数.md b/problems/0222.完全二叉树的节点个数.md
index b87877c9..10ac8264 100644
--- a/problems/0222.完全二叉树的节点个数.md
+++ b/problems/0222.完全二叉树的节点个数.md
@@ -188,7 +188,7 @@ public:
```CPP
if (root == nullptr) return 0;
-// 开始根据做深度和有深度是否相同来判断该子树是不是满二叉树
+// 开始根据左深度和右深度是否相同来判断该子树是不是满二叉树
TreeNode* left = root->left;
TreeNode* right = root->right;
int leftDepth = 0, rightDepth = 0; // 这里初始为0是有目的的,为了下面求指数方便
@@ -843,3 +843,4 @@ impl Solution {
+
diff --git a/problems/0376.摆动序列.md b/problems/0376.摆动序列.md
index 723d1d9a..efb9c6b6 100644
--- a/problems/0376.摆动序列.md
+++ b/problems/0376.摆动序列.md
@@ -53,21 +53,64 @@
**实际操作上,其实连删除的操作都不用做,因为题目要求的是最长摆动子序列的长度,所以只需要统计数组的峰值数量就可以了(相当于是删除单一坡度上的节点,然后统计长度)**
-**这就是贪心所贪的地方,让峰值尽可能的保持峰值,然后删除单一坡度上的节点**。
+**这就是贪心所贪的地方,让峰值尽可能的保持峰值,然后删除单一坡度上的节点**
-本题代码实现中,还有一些技巧,例如统计峰值的时候,数组最左面和最右面是最不好统计的。
+在计算是否有峰值的时候,大家知道遍历的下标i ,计算prediff(nums[i] - nums[i-1]) 和 curdiff(nums[i+1] - nums[i]),如果`prediff < 0 && curdiff > 0` 或者 `prediff > 0 && curdiff < 0` 此时就有波动就需要统计。
-例如序列[2,5],它的峰值数量是2,如果靠统计差值来计算峰值个数就需要考虑数组最左面和最右面的特殊情况。
+这是我们思考本题的一个大题思路,但本题要考虑三种情况:
-所以可以针对序列[2,5],可以假设为[2,2,5],这样它就有坡度了即preDiff = 0,如图:
+1. 情况一:上下坡中有平坡
+2. 情况二:数组首尾两端
+3. 情况三:单调坡中有平坡
+
+### 情况一:上下坡中有平坡
+
+例如 [1,2,2,2,1]这样的数组,如图:
+
+
+
+它的摇摆序列长度是多少呢? **其实是长度是3**,也就是我们在删除的时候 要不删除左面的三个2,要不就删除右边的三个2。
+
+如图,可以统一规则,删除左边的三个2:
+
+
+
+在图中,当i指向第一个2的时候,`prediff > 0 && curdiff = 0` ,当 i 指向最后一个2的时候 `prediff = 0 && curdiff < 0`。
+
+如果我们采用,删左面三个2的规则,那么 当 `prediff = 0 && curdiff < 0` 也要记录一个峰值,因为他是把之前相同的元素都删掉留下的峰值。
+
+所以我们记录峰值的条件应该是: `(preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)`,为什么这里允许 prediff == 0 ,就是为了 上面我说的这种情况。
+
+
+### 情况二:数组首尾两端
+
+
+所以本题统计峰值的时候,数组最左面和最右面如果统计呢?
+
+题目中说了,如果只有两个不同的元素,那摆动序列也是2。
+
+例如序列[2,5],如果靠统计差值来计算峰值个数就需要考虑数组最左面和最右面的特殊情况。
+
+因为我们在计算 prediff(nums[i] - nums[i-1]) 和 curdiff(nums[i+1] - nums[i])的时候,至少需要三个数字才能计算,而数组只有两个数字。
+
+这里我们可以写死,就是 如果只有两个元素,且元素不同,那么结果为2。
+
+不写死的话,如果和我们的判断规则结合在一起呢?
+
+可以假设,数组最前面还有一个数字,那这个数字应该是什么呢?
+
+之前我们在 讨论 情况一:相同数字连续 的时候, prediff = 0 ,curdiff < 0 或者 >0 也记为波谷。
+
+那么为了规则统一,针对序列[2,5],可以假设为[2,2,5],这样它就有坡度了即preDiff = 0,如图:

针对以上情形,result初始为1(默认最右面有一个峰值),此时curDiff > 0 && preDiff <= 0,那么result++(计算了左面的峰值),最后得到的result就是2(峰值个数为2即摆动序列长度为2)
-C++代码如下(和上图是对应的逻辑):
+经过以上分析后,我们可以写出如下代码:
-```CPP
+```CPP
+// 版本一
class Solution {
public:
int wiggleMaxLength(vector
+
diff --git a/problems/0827.最大人工岛.md b/problems/0827.最大人工岛.md
index fb0c797e..05d82f7e 100644
--- a/problems/0827.最大人工岛.md
+++ b/problems/0827.最大人工岛.md
@@ -3,8 +3,11 @@
参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!
+ # 827. 最大人工岛 +[力扣链接](https://leetcode.cn/problems/making-a-large-island/) + 给你一个大小为 n x n 二进制矩阵 grid 。最多 只能将一格 0 变成 1 。 返回执行此操作后,grid 中最大的岛屿面积是多少? @@ -30,7 +33,9 @@ 本题的一个暴力想法,应该是遍历地图尝试 将每一个 0 改成1,然后去搜索地图中的最大的岛屿面积。 -计算地图的最大面积:遍历地图 + 深搜岛屿,时间复杂度为 n * n +计算地图的最大面积:遍历地图 + 深搜岛屿,时间复杂度为 n * n。 + +(其实使用深搜还是广搜都是可以的,其目的就是遍历岛屿做一个标记,相当于染色,那么使用哪个遍历方式都行,以下我用深搜来讲解) 每改变一个0的方格,都需要重新计算一个地图的最大面积,所以 整体时间复杂度为:n^4。 @@ -41,7 +46,7 @@ 其实每次深搜遍历计算最大岛屿面积,我们都做了很多重复的工作。 -只要把深搜就可以并每个岛屿的面积记录下来就好。 +只要用一次深搜把每个岛屿的面积记录下来就好。 第一步:一次遍历地图,得出各个岛屿的面积,并做编号记录。可以使用map记录,key为岛屿编号,value为岛屿面积 第二步:在遍历地图,遍历0的方格(因为要将0变成1),并统计该1(由0变成的1)周边岛屿面积,将其相邻面积相加在一起,遍历所有 0 之后,就可以得出 选一个0变成1 之后的最大面积。 @@ -74,7 +79,7 @@ void dfs(vector