This commit is contained in:
youngyangyang04
2020-11-25 08:59:48 +08:00
parent 7b5a8c30e3
commit 0026ea3196
20 changed files with 284 additions and 91 deletions

View File

@ -169,6 +169,10 @@
* [回溯算法:解数独](https://mp.weixin.qq.com/s/eWE9TapVwm77yW9Q81xSZQ)
* [一篇总结带你彻底搞透回溯算法!](https://mp.weixin.qq.com/s/r73thpBnK1tXndFDtlsdCQ)
* 贪心算法
* [关于贪心算法,你该了解这些!](https://mp.weixin.qq.com/s/O935TaoHE9Eexwe_vSbRAg)
* [贪心算法:分发饼干](https://mp.weixin.qq.com/s/YSuLIAYyRGlyxbp9BNC1uw)
(持续更新中....

BIN
pics/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

View File

@ -1,5 +1,7 @@
> 解数独,理解二维递归是关键
如果对回溯法理论还不清楚的同学,可以先看这个视频[视频来了!!带你学透回溯算法(理论篇)](https://mp.weixin.qq.com/s/wDd5azGIYWjbU0fdua_qBg)
# 37. 解数独
题目地址https://leetcode-cn.com/problems/sudoku-solver/
@ -207,3 +209,7 @@ public:
如果一直跟住「代码随想录」的节奏,你会发现自己进步飞快,从思维方式到刷题习惯,都会有质的飞跃,「代码随想录」绝对值得推荐给身边的同学朋友们!
> **我是[程序员Carl](https://github.com/youngyangyang04),可以找我[组队刷题](https://img-blog.csdnimg.cn/20201115103410182.png),也可以在[B站上找到我](https://space.bilibili.com/525438321),本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在公众号:[代码随想录](https://img-blog.csdnimg.cn/20200815195519696.png),关注后就会发现和「代码随想录」相见恨晚!**
**如果感觉对你有帮助,不要吝啬给一个👍吧!**

View File

@ -1,6 +1,5 @@
> 开始排列问题
> 通知:现在已经将所有历史文章,汇总到一起,有一个整体的目录,方便录友们从前面系列开始卡了,就在公众号左下角「算法汇总」,大家去瞅瞅哈
# 46.全排列
@ -32,7 +31,7 @@
我以[1,2,3]为例,抽象成树形结构如下:
<img src='../pics/46.全排列.png' width=600> </img></div>
![46.全排列](https://img-blog.csdnimg.cn/20201124200941742.png)
## 回溯三部曲
@ -44,7 +43,7 @@
但排列问题需要一个used数组标记已经选择的元素如图橘黄色部分所示:
<img src='../pics/46.全排列.png' width=600> </img></div>
![46.全排列](https://img-blog.csdnimg.cn/20201124200941742.png)
代码如下:
@ -56,7 +55,7 @@ void backtracking (vector<int>& nums, vector<bool>& used)
* 递归终止条件
<img src='../pics/46.全排列.png' width=600> </img></div>
![46.全排列](https://img-blog.csdnimg.cn/20201124200941742.png)
可以看出叶子节点,就是收割结果的地方。
@ -140,3 +139,7 @@ public:
就酱如果感觉「代码随想录」诚意满满就帮Carl宣传一波吧
> **我是[程序员Carl](https://github.com/youngyangyang04),可以找我[组队刷题](https://img-blog.csdnimg.cn/20201115103410182.png),也可以在[B站上找到我](https://space.bilibili.com/525438321),本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在公众号:[代码随想录](https://img-blog.csdnimg.cn/20200815195519696.png),关注后就会发现和「代码随想录」相见恨晚!**
**如果感觉对你有帮助,不要吝啬给一个👍吧!**

View File

@ -1,6 +1,5 @@
> 排列也要去重了
> 通知很多录友都反馈之前看「算法汇总」的目录要一直往下拉很麻烦这次Carl将所有历史文章汇总到一篇文章中有一个整体的目录方便录友们从前面系列开始卡了依然在公众号左下角[「算法汇总」](https://mp.weixin.qq.com/s/weyitJcVHBgFtSc19cbPdw),这里会持续更新,大家快去瞅瞅哈
# 47.全排列 II
@ -37,7 +36,7 @@
我以示例中的 [1,1,2]为例 (为了方便举例,已经排序)抽象为一棵树,去重过程如图:
<img src='../pics/47.全排列II1.png' width=600> </img></div>
![47.全排列II1](https://img-blog.csdnimg.cn/20201124201331223.png)
图中我们对同一树层前一位也就是nums[i-1])如果使用过,那么就进行去重。
@ -114,11 +113,11 @@ if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == true) {
树层上去重(used[i - 1] == false),的树形结构如下:
<img src='../pics/47.全排列II2.png' width=600> </img></div>
![47.全排列II2](https://img-blog.csdnimg.cn/20201124201406192.png)
树枝上去重used[i - 1] == true的树型结构如下
<img src='../pics/47.全排列II3.png' width=600> </img></div>
![47.全排列II3](https://img-blog.csdnimg.cn/20201124201431571.png)
大家应该很清晰的看到,树层上对前一位去重非常彻底,效率很高,树枝上对前一位去重虽然最后可以得到答案,但是做了很多无用搜索。
@ -145,3 +144,7 @@ if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == true) {
就酱,很多录友表示和「代码随想录」相见恨晚,那么大家帮忙多多宣传,让更多的同学知道这里,感谢啦!
> **我是[程序员Carl](https://github.com/youngyangyang04),可以找我[组队刷题](https://img-blog.csdnimg.cn/20201115103410182.png),也可以在[B站上找到我](https://space.bilibili.com/525438321),本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在公众号:[代码随想录](https://img-blog.csdnimg.cn/20200815195519696.png),关注后就会发现和「代码随想录」相见恨晚!**
**如果感觉对你有帮助,不要吝啬给一个👍吧!**

View File

@ -228,3 +228,7 @@ public:
就酱,如果感觉「代码随想录」干货满满,就分享给身边的朋友同学吧,他们可能也需要!
> **我是[程序员Carl](https://github.com/youngyangyang04),可以找我[组队刷题](https://img-blog.csdnimg.cn/20201115103410182.png),也可以在[B站上找到我](https://space.bilibili.com/525438321),本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在公众号:[代码随想录](https://img-blog.csdnimg.cn/20200815195519696.png),关注后就会发现和「代码随想录」相见恨晚!**
**如果感觉对你有帮助,不要吝啬给一个👍吧!**

View File

@ -1,25 +1,49 @@
## 链接
https://leetcode-cn.com/problems/jump-game/
## 思路
# 55. 跳跃游戏
其实贪心和动态规划很容易混在一起,在面试中,我们应该本着能用贪心就用贪心,贪心解决不了再考虑用动态规划。 毕竟贪心更容易理解,并快速写出代码
给定一个非负整数数组,你最初位于数组的第一个位置
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
示例 2:
输入: [3,2,1,0,4]
输出: false
解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 所以你永远不可能到达最后一个位置。
## 思路
刚看到本题一开始可能想当前位置元素如果是3我究竟是跳一步呢还是两步呢还是三步呢究竟跳几步才是最优呢
其实如果本题是要求只能跳元素数值大小的个数,不能多也不能少,问是否达到终点,那么一定要用动态规划了
可以转变一下思路,不一样非要明确一次究竟跳几步,每次取最大的跳跃步数,这个就是可以跳跃的覆盖范围
这个范围内,已经是可以跳过来的,别管是怎么跳的,反正一定可以跳过来。
**那么就是这个跳跃覆盖范围究竟可不可以覆盖到终点!**
每次移动取最大跳跃步数,得到最大的覆盖范围,每移动一个单位,就更新最大覆盖范围。
**局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到就是整体最大覆盖范围,看是否能到终点**
但本题其实我们就看跳到的范围能否覆盖终点,就可以了。
那么我们每次取最大的覆盖范围,看最后能否覆盖终点。
如图:
<img src='../pics/55.跳跃游戏.png' width=600> </img></div>
![55.跳跃游戏](https://img-blog.csdnimg.cn/20201124154758229.png)
那么i每次移动只能在cover的范围内移动每移动一个元素cover得到该元素数值的补充让i继续移动下去。
i每次移动只能在cover的范围内移动每移动一个元素cover得到该元素数值(新的覆盖范围)的补充让i继续移动下去。
而cover每次只取 得到该元素数值补充后的范围 cover本身范围 的最大值
而cover每次只取 max(该元素数值补充后的范围, cover本身范围)
如果cover大于等于了终点下表直接return true就可以了。
@ -39,3 +63,8 @@ public:
}
};
```
# 总结
其实贪心和动态规划很容易混在一起,在面试中,我们应该本着能用贪心就用贪心,贪心解决不了再考虑用动态规划。 毕竟贪心更容易理解,并快速写出代码。

View File

@ -34,7 +34,7 @@
用示例中的[1, 2, 2] 来举例,如图所示: **注意去重需要先对集合排序**
<img src='../pics/90.子集II.png' width=600> </img></div>
![90.子集II](https://img-blog.csdnimg.cn/20201124195411977.png)
从图中可以看出同一树层上重复取2 就要过滤掉同一树枝上就可以重复取2因为同一树枝上元素的集合才是唯一子集
@ -114,16 +114,19 @@ public:
其实这道题目的知识点我们之前都讲过了如果之前讲过的子集问题和去重问题都掌握的好这道题目应该分分钟AC。
当然本题去重的逻辑,也可以这么写
这道题目去重的逻辑,也可以这么写
```
if (i > startIndex && nums[i] == nums[i - 1] ) {
continue;
}
}
```
**就酱,如果感觉融会贯通了,就把「代码随想录」介绍给自己的同学朋友吧,也许他们也需要!**
> 我是[程序员Carl](https://github.com/youngyangyang04)组队刷题可以找我,本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在:[代码随想录](https://img-blog.csdnimg.cn/20200815195519696.png),期待你的关注!
> **我是[程序员Carl](https://github.com/youngyangyang04),可以找我[组队刷题](https://img-blog.csdnimg.cn/20201115103410182.png),也可以在[B站上找到我](https://space.bilibili.com/525438321),本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在公众号[代码随想录](https://img-blog.csdnimg.cn/20201124161234338.png),关注后就会发现和「代码随想录」相见恨晚!**
**如果感觉题解对你有帮助,不要吝啬给一个👍吧!**

View File

@ -1,12 +1,8 @@
## 题目地址
https://leetcode-cn.com/problems/count-complete-tree-nodes/
> 今天是中秋&&国庆,所以来一道二叉树简单题吧
如果之前两篇[二叉树:看看这些树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg) [二叉树:看看这些树的最小深度](https://mp.weixin.qq.com/s/BH8-gPC3_QlqICDg7rGSGA)都认真看了的话,这道题目可以分分钟刷掉了哈哈。
# 222.完全二叉树的节点个数
题目地址https://leetcode-cn.com/problems/count-complete-tree-nodes/
给出一个完全二叉树,求出该树的节点个数。
示例:
@ -15,17 +11,17 @@ https://leetcode-cn.com/problems/count-complete-tree-nodes/
# 思路
这道题目其实没有必要强调是完全二叉树,就是求二叉树节点的个数
本篇给出按照普通二叉树的求法以及利用完全二叉树性质的求法
![image.png](https://pic.leetcode-cn.com/168a07d49c103ada57202f5ad60a2d51f3d0e0ea5c8399e1caed81b709153c85-image.png)
## 普通二叉树
依然可以使用递归法和迭代法来解决
首先按照普通二叉树的逻辑来求
这道题目的递归法和求二叉树的深度写法类似, 而迭代法,[二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/Gb3BjakIKGNpup2jYtTzog)遍历模板稍稍修改一下,记录遍历的节点数量就可以了。
递归遍历的顺序依然是后序(左右中)。
## 递归
### 递归
如果对求二叉树深度还不熟悉的话,看这篇:[二叉树:看看这些树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg)。
@ -49,15 +45,16 @@ if (cur == NULL) return 0;
代码如下:
```
int leftNum = getNodesNum(cur->left); // 左
int rightNum = getNodesNum(cur->right); // 右
int treeNum = leftNum + rightNum + 1; // 中
return treeNum;
int leftNum = getNodesNum(cur->left); // 左
int rightNum = getNodesNum(cur->right); // 右
int treeNum = leftNum + rightNum + 1; // 中
return treeNum;
```
所以整体C++代码如下:
```
// 版本一
class Solution {
private:
int getNodesNum(TreeNode* cur) {
@ -76,6 +73,7 @@ public:
代码精简之后C++代码如下:
```
// 版本二
class Solution {
public:
int countNodes(TreeNode* root) {
@ -83,10 +81,15 @@ public:
return 1 + countNodes(root->left) + countNodes(root->right);
}
};
```
## 迭代法
时间复杂度O(n)
空间复杂度O(logn),算上了递归系统栈占用的空间
**网上基本都是这个精简的代码版本,其实不建议大家照着这个来写,代码确实精简,但隐藏了一些内容,连遍历的顺序都看不出来,所以初学者建议学习版本一的代码,稳稳的打基础**
### 迭代法
如果对求二叉树层序遍历还不熟悉的话,看这篇:[二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/Gb3BjakIKGNpup2jYtTzog)。
@ -113,15 +116,57 @@ public:
}
};
```
时间复杂度O(n)
空间复杂度O(n)
# 总结
## 完全二叉树
这道题目的解法其实我们在[二叉树:看看这些树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg)和 [二叉树:看看这些树的最小深度](https://mp.weixin.qq.com/s/BH8-gPC3_QlqICDg7rGSGA)都有提到过了
以上方法都是按照普通二叉树来做的,对于完全二叉树特性不了解的同学可以看这篇 [关于二叉树,你该了解这些!](https://mp.weixin.qq.com/s/_ymfWYvTNd2GvWvC5HOE4A),这篇详细介绍了各种二叉树的特性
一样的分析套路,代码也差不多,估计此时大家最这一类求二叉树节点数量以及求深度应该非常熟练了
完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满
没有做过这道题目的同学可以愉快的刷了它了
对于情况一,可以直接用 2^树深度 - 1 来计算注意这里根节点深度为1
最后祝大家中秋&国庆节日愉快哈!
对于情况二分别递归左孩子和右孩子递归到某一深度一定会有左孩子或者右孩子为满二叉树然后依然可以按照情况1来计算。
完全二叉树(一)如图:
![222.完全二叉树的节点个数](https://img-blog.csdnimg.cn/20201124092543662.png)
完全二叉树(二)如图:
![222.完全二叉树的节点个数1](https://img-blog.csdnimg.cn/20201124092634138.png)
可以看出如果整个树不是满二叉树,就递归其左右孩子,直到遇到满二叉树为止,用公式计算这个子树(满二叉树)的节点数量。
C++代码如下:
```C++
class Solution {
public:
int countNodes(TreeNode* root) {
if (root == nullptr) return 0;
TreeNode* left = root->left;
TreeNode* right = root->right;
int leftHeight = 0, rightHeight = 0; // 这里初始为0是有目的的为了下面求指数方便
while (left) { // 求左子树深度
left = left->left;
leftHeight++;
}
while (right) { // 求右子树深度
right = right->right;
rightHeight++;
}
if (leftHeight == rightHeight) {
return (2 << leftHeight) - 1; // 注意(2<<1) 相当于2^2所以leftHeight初始为0
}
return countNodes(root->left) + countNodes(root->right) + 1;
}
};
```
时间复杂度O(logn * logn)
空间复杂度O(logn)
> **我是[程序员Carl](https://github.com/youngyangyang04),可以找我[组队刷题](https://img-blog.csdnimg.cn/20201115103410182.png),也可以在[B站上找到我](https://space.bilibili.com/525438321),本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在公众号:[代码随想录](https://img-blog.csdnimg.cn/20200815195519696.png),关注后就会发现和「代码随想录」相见恨晚!**
**如果感觉对你有帮助,不要吝啬给一个👍吧!**
> 更多算法干货文章持续更新可以微信搜索「代码随想录」第一时间围观关注后回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等就可以获得我多年整理的学习资料。

View File

@ -101,7 +101,7 @@ void backtracking(参数) {
本题以输入:[["JFK", "KUL"], ["JFK", "NRT"], ["NRT", "JFK"]为例,抽象为树形结构如下:
<img src='https://img-blog.csdnimg.cn/2020111518065555.png' width=600> </img></div>
![332.重新安排行程1](https://img-blog.csdnimg.cn/2020111518065555.png)
开始回溯三部曲讲解:
@ -127,7 +127,7 @@ bool backtracking(int ticketNum, vector<string>& result) {
因为我们只需要找到一个行程,就是在树形结构中唯一的一条通向叶子节点的路线,如图:
<img src='https://img-blog.csdnimg.cn/2020111518065555.png' width=600> </img></div>
![332.重新安排行程1](https://img-blog.csdnimg.cn/2020111518065555.png)
所以找到了这个叶子节点了直接返回,这个递归函数的返回值问题我们在讲解二叉树的系列的时候,在这篇[二叉树:递归函数究竟什么时候需要返回值,什么时候不要返回值?](https://mp.weixin.qq.com/s/6TWAVjxQ34kVqROWgcRFOg)详细介绍过。
@ -246,4 +246,7 @@ for (pair<string, int>target : targets[result[result.size() - 1]])
就酱很多录友表示和「代码随想录」相见恨晚那么帮Carl宣传一波吧让更多同学知道这里
> 更多算法干货文章持续更新可以微信搜索「代码随想录」第一时间围观关注后回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等就可以获得我多年整理的学习资料。
> **我是[程序员Carl](https://github.com/youngyangyang04),可以找我[组队刷题](https://img-blog.csdnimg.cn/20201115103410182.png),也可以在[B站上找到我](https://space.bilibili.com/525438321),本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在公众号:[代码随想录](https://img-blog.csdnimg.cn/20200815195519696.png),关注后就会发现和「代码随想录」相见恨晚!**
**如果感觉对你有帮助,不要吝啬给一个👍吧!**

View File

@ -1,44 +1,75 @@
题目链接: https://leetcode-cn.com/problems/wiggle-subsequence/
> 本周讲解了[贪心理论基础](https://mp.weixin.qq.com/s/O935TaoHE9Eexwe_vSbRAg),以及第一道贪心的题目:[贪心算法:分发饼干](https://mp.weixin.qq.com/s/YSuLIAYyRGlyxbp9BNC1uw),可能会给大家一种贪心算法比较简单的错觉,好了,接下来几天的题目难度要上来了,哈哈。
# 376. 摆动序列
题目链接https://leetcode-cn.com/problems/wiggle-subsequence/
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。
例如, [1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3) 是正负交替出现的。相反, [1,4,7,2,5] 和 [1,7,4,5,5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。
给定一个整数序列,返回作为摆动序列的最长子序列的长度。 通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。
示例 1:
输入: [1,7,4,9,2,5]
输出: 6
解释: 整个序列均为摆动序列。
示例 2:
输入: [1,17,5,10,13,15,10,5,16,8]
输出: 7
解释: 这个序列包含几个长度为 7 摆动序列,其中一个可为[1,17,10,13,10,16,8]。
示例 3:
输入: [1,2,3,4,5,6,7,8,9]
输出: 2
## 思路
本题要求通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。
相信这么一说吓退不少同学,这又可以修改数组,这得如何修改呢?
相信这么一说吓退不少同学,这要求最大摆动序列又可以修改数组,这得如何修改呢?
我们来分析一下,要求删除元素使其达到最大摆动序列,应该删除什么元素呢?
来分析一下,要求删除元素使其达到最大摆动序列,应该删除什么元素呢?
用示例二来举例,如图所示:
<img src='../pics/376.摆动序列.png' width=600> </img></div>
![376.摆动序列](https://img-blog.csdnimg.cn/20201124174327597.png)
图中可以看出,为了让摆动序列最长,只需要把单一坡度(递增或者递减)上的节点删掉就可以了
**局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值**
**整体最优:整个序列有最多的局部峰值,从而达到最长摆动序列**
局部最优推出全局最优,并举不出反例,那么试试贪心!
(为方便表述,以下说的峰值都是指局部峰值)
**实际操作上,其实连删除的操作都不用做,因为题目要求的是最长摆动子序列的长度,所以只需要统计数组的峰值数量就可以了(相当于是删除单一坡度上的节点,然后统计长度)**
**这就是贪心所贪的地方,让峰值尽可能的保持峰值,然后删除单一坡度上的节点**
**实际操作上,其实练删除的操作都不用做,因为题目要求的是摆动序列的长度,所以只需要统计数组的峰值数量就可以了(相当于是删除单一坡度上的节点,然后统计长度)**
本题代码实现中,还有一些技巧,例如统计峰值的时候,数组最左面和最右面是最不好统计的。
代码实现中,还有一些技巧,例如统计峰值的时候,数组最左面和最右面是最不好统计的。
例如序列[2,5]它的峰值数量是2如果靠统计差值来计算峰值个数就需要考虑数组最左面和最右面的特殊情况
例如数组[2,5]它的峰值数量是2如果靠统计差值来计算峰值就需要考虑数组最左面和最右面的特殊情况。
所以可以针对序列[2,5],可以假设为[2,2,5]这样它就有坡度了即preDiff = 0如图
所以可以针对数组[2,5],假设为[2,2,5],这样它就有坡度了,如图:
![376.摆动序列1](https://img-blog.csdnimg.cn/20201124174357612.png)
<img src='../pics/376.摆动序列1.png' width=600> </img></div>
这样result初始为1curDiff > 0 && preDiff <= 0result++最后得到的result就是2了。
针对以上情形result初始为1默认最右面有一个峰值此时curDiff > 0 && preDiff <= 0那么result++计算了左面的峰值最后得到的result就是2峰值个数为2即摆动序列长度为2
C++代码如下:
```
```C++
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if (nums.size() <= 1) return nums.size();
int curDiff = 0; // 当前一对差值
int preDiff = 0; // 前一对差值
int result = 1; // 记录峰值起始位置峰值为1
int result = 1; // 记录峰值个数,序列默认序列最右边有一个峰值
for (int i = 1; i < nums.size(); i++) {
curDiff = nums[i] - nums[i - 1];
// 出现峰值
@ -51,6 +82,25 @@ public:
}
};
```
时间复杂度O(n)
空间复杂度O(1)
# 总结
**贪心的题目说简单有的时候就是常识,说难就难在都不知道该怎么用贪心**
本题大家如果要去模拟删除元素达到最长摆动子序列的过程,那指定绕里面去了,一时半会拔不出来。
而这道题目有什么技巧说一下子能想到贪心么?
其实也没有,类似的题目做过了就会想到。
此时大家就应该了解了:保持区间波动,只需要把单调区间上的元素移除就可以了。
就酱,「代码随想录」值得介绍给身边每一位学习算法的同学!
> **我是[程序员Carl](https://github.com/youngyangyang04),可以找我[组队刷题](https://img-blog.csdnimg.cn/20201115103410182.png),也可以在[B站上找到我](https://space.bilibili.com/525438321),本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在公众号:[代码随想录](https://img-blog.csdnimg.cn/20201124161234338.png),关注后就会发现和「代码随想录」相见恨晚!**
**如果感觉题解对你有帮助,不要吝啬给一个👍吧!**
> 我是[程序员Carl](https://github.com/youngyangyang04),组队刷题可以找我,本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在:[代码随想录](https://img-blog.csdnimg.cn/20200815195519696.png),期待你的关注!

View File

@ -28,9 +28,9 @@
 
提示:
* 1 <= g.length <= 3 * 104
* 0 <= s.length <= 3 * 104
* 1 <= g[i], s[j] <= 231 - 1
* 1 <= g.length <= 3 * 10^4
* 0 <= s.length <= 3 * 10^4
* 1 <= g[i], s[j] <= 2^31 - 1
## 思路
@ -79,6 +79,29 @@ public:
有的同学看到要遍历两个数组就想到用两个for循环那样逻辑其实就复杂了。
**也可以换一个思路,小饼干先喂饱小胃口**
代码如下:
```
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(),g.end());
sort(s.begin(),s.end());
int res = 0;
int index = 0;
for(int i = 0;i < s.size();++i){
if(index < g.size() && g[index] <= s[i]){
index++;
res++;
}
}
return res;
}
};
```
# 总结
这道题是贪心很好的一道入门题目,思路还是比较容易想到的。
@ -87,5 +110,8 @@ public:
就酱,「代码随想录」值得介绍给身边的朋友同学们!
> 我是[程序员Carl](https://github.com/youngyangyang04)组队刷题可以找我,本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在:[代码随想录](https://img-blog.csdnimg.cn/20200815195519696.png)期待你的关注!
> **我是[程序员Carl](https://github.com/youngyangyang04),可以找我[组队刷题](https://img-blog.csdnimg.cn/20201115103410182.png),也可以在[B站上找到我](https://space.bilibili.com/525438321),本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在公众号[代码随想录](https://img-blog.csdnimg.cn/20200815195519696.png)关注后就会发现和「代码随想录」相见恨晚!**
**如果感觉题解对你有帮助,不要吝啬给一个👍吧!**

View File

@ -1,4 +1,3 @@
## 题目地址
> 和子集问题有点像,但又处处是陷阱
@ -37,7 +36,7 @@
为了有鲜明的对比,我用[4, 7, 6, 7]这个数组来举例,抽象为树形结构如图:
<img src='../pics/491. 递增子序列1.png' width=600> </img></div>
![491. 递增子序列1](https://img-blog.csdnimg.cn/20201124200229824.png)
## 回溯三部曲
@ -69,30 +68,8 @@ if (path.size() > 1) {
* 单层搜索逻辑
<img src='../pics/491. 递增子序列1.png' width=600> </img></div>
在图中可以看出,**同一父节点下的同层上使用过的元素就不能在使用了**,注意这里要求的是**同一父节点下的同层**,这里和[回溯算法:求子集问题(二)](https://mp.weixin.qq.com/s/WJ4JNDRJgsW3eUN72Hh3uQ)中去重的有本质区别。
[回溯算法:求子集问题(二)](https://mp.weixin.qq.com/s/WJ4JNDRJgsW3eUN72Hh3uQ)是要整棵树的同一层进行去重,所以进行排序!
如图:
![491. 递增子序列4](https://img-blog.csdnimg.cn/20201112162206843.png)
**本题只要同一父节点下的同层上重复使用元素,递增子序列就会重复**,而[回溯算法:求子集问题(二)](https://mp.weixin.qq.com/s/WJ4JNDRJgsW3eUN72Hh3uQ)中是排序之后看相邻元素是否重复使用。
还有一种情况就是如果选取的元素小于子序列最后一个元素那么就不能是递增的所以也要pass掉。
那么去重的逻辑代码如下:
```
if ((!path.empty() && nums[i] < path.back())
|| uset.find(nums[i]) != uset.end()) {
continue;
}
```
判断`nums[i] < path.back()`之前一定要判断path是否为空所以是`!path.empty() && nums[i] < path.back()`
`uset.find(nums[i]) != uset.end()`判断nums[i]在本层是否使用过。
![491. 递增子序列1](https://img-blog.csdnimg.cn/20201124200229824.png)
在图中可以看出,**同一父节点下的同层上使用过的元素就不能在使用了**
那么单层搜索代码如下:
@ -213,3 +190,7 @@ public:
**就酱如果感觉「代码随想录」很干货就帮Carl宣传一波吧**
> **我是[程序员Carl](https://github.com/youngyangyang04),可以找我[组队刷题](https://img-blog.csdnimg.cn/20201115103410182.png),也可以在[B站上找到我](https://space.bilibili.com/525438321),本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在公众号:[代码随想录](https://img-blog.csdnimg.cn/20200815195519696.png),关注后就会发现和「代码随想录」相见恨晚!**
**如果感觉对你有帮助,不要吝啬给一个👍吧!**

View File

@ -0,0 +1,32 @@
// 这道题小细节很多
// 感觉这道题可以用回溯法啊
// 转为01 背包 思路不好想啊
// dp数组难在如何初始化
// dp 数组 通常比较长
```
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int S) {
int sum = 0;
for (int i = 0; i < nums.size(); i++) sum += nums[i];
if (S > sum) return 0; // 此时没有方案
if ((S + sum) % 2) return 0; // 此时没有方案两个int相加的时候要各位小心数值溢出的问题
int bagSize = (S + sum) / 2;
int dp[1001] = {1};
//for (int i = 0; i < nums.size(); i++) dp[nums[i]] = 1;
for (int i = 0; i < nums.size(); i++) {
for (int j = bagSize; j >= nums[i]; j--) {
if (j - nums[i] >= 0) dp[j] += dp[j - nums[i]];
}
//for (int k = 0; k <= bagSize; k++) {
// cout << dp[k] << " ";
//}
//cout << endl;
}
return dp[bagSize];
}
};
```

View File

@ -1,5 +1,5 @@
# 本周小结!(回溯算法系列三)续集 o
# 本周小结!(回溯算法系列三)续集
> 在 [本周小结!(回溯算法系列三)](https://mp.weixin.qq.com/s/tLkt9PSo42X60w8i94ViiA) 中一位录友对 整颗树的本层和同一节点的本层有疑问,也让我重新思考了一下,发现这里确实有问题,所以专门写一篇来纠正,感谢录友们的积极交流哈!
@ -239,3 +239,7 @@ used数组可是全局变量每层与每层之间公用一个used数组
就酱,「代码随想录」一直都是干货满满,公众号里的一抹清流,值得推荐给身边的每一位同学朋友!
> **我是[程序员Carl](https://github.com/youngyangyang04),可以找我[组队刷题](https://img-blog.csdnimg.cn/20201115103410182.png),也可以在[B站上找到我](https://space.bilibili.com/525438321),本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在公众号:[代码随想录](https://img-blog.csdnimg.cn/20200815195519696.png),关注后就会发现和「代码随想录」相见恨晚!**
**如果感觉对你有帮助,不要吝啬给一个👍吧!**