diff --git a/README.md b/README.md index dd8590e0..a527841e 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,12 @@ ![算法面试知识大纲](https://img-blog.csdnimg.cn/20200729181420491.png) -# 算法视频讲解 +# B站算法视频讲解 -* [KMP算法(理论篇)B站视频](https://www.bilibili.com/video/BV1PD4y1o7nd) -* [KMP算法(代码篇)B站视频](https://www.bilibili.com/video/BV1M5411j7Xx) -* [回溯算法(理论篇)B站视频](https://www.bilibili.com/video/BV1cy4y167mM) +* [KMP算法(理论篇)](https://www.bilibili.com/video/BV1PD4y1o7nd) +* [KMP算法(代码篇)](https://www.bilibili.com/video/BV1M5411j7Xx) +* [回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM) +* [回溯算法之组合问题(力扣题目:77.组合)](https://www.bilibili.com/video/BV1ti4y1L7cv) (持续更新中....) @@ -417,6 +418,7 @@ |[0434.字符串中的单词数](https://github.com/youngyangyang04/leetcode/blob/master/problems/0434.字符串中的单词数.md) |字符串 |简单|**模拟**| |[0435.无重叠区间](https://github.com/youngyangyang04/leetcode/blob/master/problems/0435.无重叠区间.md) |贪心 |中等|**贪心** 经典题目,有点难| |[0450.删除二叉搜索树中的节点](https://github.com/youngyangyang04/leetcode/blob/master/problems/0450.删除二叉搜索树中的节点.md) |树 |中等|**递归**| +|[0452.用最少数量的箭引爆气球](https://github.com/youngyangyang04/leetcode/blob/master/problems/0452.用最少数量的箭引爆气球.md) |贪心/排序 |中等|**贪心** 经典题目| |[0454.四数相加II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0454.四数相加II.md) |哈希表 |中等| **哈希**| |[0455.分发饼干](https://github.com/youngyangyang04/leetcode/blob/master/problems/0455.分发饼干.md) |贪心 |简单| **贪心**| |[0459.重复的子字符串](https://github.com/youngyangyang04/leetcode/blob/master/problems/0459.重复的子字符串.md) |字符创 |简单| **KMP**| @@ -454,6 +456,7 @@ |[0977.有序数组的平方](https://github.com/youngyangyang04/leetcode/blob/master/problems/0977.有序数组的平方.md) |数组 |中等|**双指针** 还是比较巧妙的| |[1002.查找常用字符](https://github.com/youngyangyang04/leetcode/blob/master/problems/1002.查找常用字符.md) |栈 |简单|**栈**| |[1047.删除字符串中的所有相邻重复项](https://github.com/youngyangyang04/leetcode/blob/master/problems/1047.删除字符串中的所有相邻重复项.md) |哈希表 |简单|**哈希表/数组**| +|[1049.最后一块石头的重量II](https://github.com/youngyangyang04/leetcode/blob/master/problems/1049.最后一块石头的重量II.md) |动态规划 |中等|**01背包**| |[1207.独一无二的出现次数](https://github.com/youngyangyang04/leetcode/blob/master/problems/1207.独一无二的出现次数.md) |哈希表 |简单|**哈希** 两层哈希| |[1356.根据数字二进制下1的数目排序](https://github.com/youngyangyang04/leetcode/blob/master/problems/1356.根据数字二进制下1的数目排序.md) |位运算 |简单|**位运算** 巧妙的计算二进制中1的数量| |[1365.有多少小于当前数字的数字](https://github.com/youngyangyang04/leetcode/blob/master/problems/1365.有多少小于当前数字的数字.md) |数组、哈希表 |简单|**哈希** 从后遍历的技巧很不错| diff --git a/pics/452.用最少数量的箭引爆气球.png b/pics/452.用最少数量的箭引爆气球.png new file mode 100644 index 00000000..64080914 Binary files /dev/null and b/pics/452.用最少数量的箭引爆气球.png differ diff --git a/pics/455.分发饼干.png b/pics/455.分发饼干.png index ae66b57f..17e15e09 100644 Binary files a/pics/455.分发饼干.png and b/pics/455.分发饼干.png differ diff --git a/pics/93_复原IP地址.png b/pics/93_复原IP地址.png deleted file mode 100644 index 8e3a9feb..00000000 Binary files a/pics/93_复原IP地址.png and /dev/null differ diff --git a/problems/0017.电话号码的字母组合.md b/problems/0017.电话号码的字母组合.md index 53da5572..e6d28496 100644 --- a/problems/0017.电话号码的字母组合.md +++ b/problems/0017.电话号码的字母组合.md @@ -1,7 +1,4 @@ -## 题目地址 -https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/ - > 多个集合求组合问题。 # 17.电话号码的字母组合 @@ -60,7 +57,7 @@ const string letterMap[10] = { 例如:输入:"23",抽象为树形结构,如图所示: - +![17. 电话号码的字母组合](https://img-blog.csdnimg.cn/20201123200304469.png) 图中可以看出遍历的深度,就是输入"23"的长度,而叶子节点就是我们要收集的结果,输出["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]。 @@ -232,4 +229,7 @@ public: **就酱,如果学到了,就帮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),关注后就会发现和「代码随想录」相见恨晚!** + +**如果感觉对你有帮助,不要吝啬给一个👍吧!** + diff --git a/problems/0027.移除元素.md b/problems/0027.移除元素.md index 7700fcf3..71f2af5c 100644 --- a/problems/0027.移除元素.md +++ b/problems/0027.移除元素.md @@ -112,5 +112,7 @@ public: }; ``` +拓展: 也可以一个指向前面,一个指向后面,遇到需要删除的就交换,最后返回指针的位置加1,只不过这么做更改了数组元素的位置了,不算是移除元素。 + > 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。 diff --git a/problems/0039.组合总和.md b/problems/0039.组合总和.md index 7f624938..509ad28f 100644 --- a/problems/0039.组合总和.md +++ b/problems/0039.组合总和.md @@ -39,7 +39,7 @@ candidates 中的数字可以无限制重复被选取。 本题搜索的过程抽象成树形结构如下: - +![39.组合总和](https://img-blog.csdnimg.cn/20201123202227835.png) 注意图中叶子节点的返回条件,因为本题没有组合数量要求,仅仅是总和的限制,所以递归没有层数的限制,只要选取的元素总和超过target,就返回! @@ -75,7 +75,7 @@ void backtracking(vector& candidates, int target, int sum, int startIndex) 在如下树形结构中: - +![39.组合总和](https://img-blog.csdnimg.cn/20201123202227835.png) 从叶子节点可以清晰看到,终止只有两种情况,sum大于target和sum等于target。 @@ -148,7 +148,7 @@ public: 在这个树形结构中: - +![39.组合总和](https://img-blog.csdnimg.cn/20201123202227835.png) 以及上面的版本一的代码大家可以看到,对于sum已经大于target的情况,其实是依然进入了下一层递归,只是下一层递归结束判断的时候,会判断sum > target的话就返回。 @@ -160,7 +160,7 @@ public: 如图: - +![39.组合总和1](https://img-blog.csdnimg.cn/20201123202349897.png) for循环剪枝代码如下: @@ -222,3 +222,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),关注后就会发现和「代码随想录」相见恨晚!** + +**如果感觉对你有帮助,不要吝啬给一个👍吧!** + diff --git a/problems/0040.组合总和II.md b/problems/0040.组合总和II.md index 7f07eef8..40179710 100644 --- a/problems/0040.组合总和II.md +++ b/problems/0040.组合总和II.md @@ -1,6 +1,5 @@ > 这篇可以说是全网把组合问题如何去重,讲的最清晰的了! - # 40.组合总和II 题目链接:https://leetcode-cn.com/problems/combination-sum-ii/ @@ -65,7 +64,7 @@ candidates 中的每个数字在每个组合中只能使用一次。 选择过程树形结构如图所示: - +![40.组合总和II](https://img-blog.csdnimg.cn/20201123202736384.png) 可以看到图中,每个节点相对于 [39.组合总和](https://mp.weixin.qq.com/s/FLg8G6EjVcxBjwCbzpACPw)我多加了used数组,这个used数组下面会重点介绍。 @@ -115,7 +114,7 @@ if (sum == target) { 这块比较抽象,如图: - +![40.组合总和II1](https://img-blog.csdnimg.cn/20201123202817973.png) 我在图中将used的变化用橘黄色标注上,可以看出在candidates[i] == candidates[i - 1]相同的情况下: @@ -201,4 +200,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),关注后就会发现和「代码随想录」相见恨晚!** + +**如果感觉对你有帮助,不要吝啬给一个👍吧!** diff --git a/problems/0077.组合.md b/problems/0077.组合.md index d32112d6..0a7187d1 100644 --- a/problems/0077.组合.md +++ b/problems/0077.组合.md @@ -75,7 +75,7 @@ for (int i = 1; i <= n; i++) { 那么我把组合问题抽象为如下树形结构: - +![77.组合](https://img-blog.csdnimg.cn/20201123195223940.png) 可以看出这个棵树,一开始集合是 1,2,3,4, 从左向右取数,取过的数,不在重复取。 @@ -119,7 +119,7 @@ vector path; // 用来存放符合条件结果 从下图中红线部分可以看出,在集合[1,2,3,4]取1之后,下一层递归,就要在[2,3,4]中取数了,那么下一层递归如何知道从[2,3,4]中取数呢,靠的就是startIndex。 - +![77.组合2](https://img-blog.csdnimg.cn/20201123195328976.png) 所以需要startIndex来记录下一层递归,搜索的起始位置。 @@ -139,7 +139,7 @@ path这个数组的大小如果达到k,说明我们找到了一个子集大小 如图红色部分: - +![77.组合3](https://img-blog.csdnimg.cn/20201123195407907.png) 此时用result二维数组,把path保存起来,并终止本层递归。 @@ -156,7 +156,7 @@ if (path.size() == k) { 回溯法的搜索过程就是一个树型结构的遍历过程,在如下图中,可以看出for循环用来横向遍历,递归的过程是纵向遍历。 - +![77.组合1](https://img-blog.csdnimg.cn/20201123195242899.png) 如此我们才遍历完图中的这棵树。 @@ -241,3 +241,8 @@ void backtracking(参数) { **[本题剪枝操作文章链接](https://mp.weixin.qq.com/s/Ri7spcJMUmph4c6XjPWXQA)** + +> **我是[程序员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),关注后就会发现和「代码随想录」相见恨晚!** + +**如果感觉对你有帮助,不要吝啬给一个👍吧!** + diff --git a/problems/0078.子集.md b/problems/0078.子集.md index 05bc45c0..8a2ff8a3 100644 --- a/problems/0078.子集.md +++ b/problems/0078.子集.md @@ -38,7 +38,7 @@ 以示例中nums = [1,2,3]为例把求子集抽象为树型结构,如下: - +![78.子集](https://img-blog.csdnimg.cn/202011232041348.png) 从图中红线部分,可以看出**遍历这个树的时候,把所有节点都记录下来,就是要求的子集集合**。 @@ -62,7 +62,7 @@ void backtracking(vector& nums, int startIndex) { 从图中可以看出: - +![78.子集](https://img-blog.csdnimg.cn/202011232041348.png) 剩余集合为空的时候,就是叶子节点。 @@ -169,3 +169,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),关注后就会发现和「代码随想录」相见恨晚!** + +**如果感觉对你有帮助,不要吝啬给一个👍吧!** + diff --git a/problems/0093.复原IP地址.md b/problems/0093.复原IP地址.md index c7150033..e691852e 100644 --- a/problems/0093.复原IP地址.md +++ b/problems/0093.复原IP地址.md @@ -1,5 +1,3 @@ -## 题目地址 - > 一些录友表示跟不上现在的节奏,想从头开始打卡学习起来,可以在公众号左下方,「算法汇总」可以找到历史文章,都是按系列排好顺序的,挨个看就可以了,看文章下的留言你就会发现,有很多录友都在从头打卡,你并不孤单! # 93.复原IP地址 @@ -47,7 +45,7 @@ s 仅由数字组成 切割问题可以抽象为树型结构,如图: - +![93.复原IP地址](https://img-blog.csdnimg.cn/20201123203735933.png) ## 回溯三部曲 @@ -98,7 +96,7 @@ if (pointNum == 3) { // 逗点数量为3时,分隔结束 如果不合法就结束本层循环,如图中剪掉的分支: - +![93.复原IP地址](https://img-blog.csdnimg.cn/20201123203735933.png) 然后就是递归和回溯的过程: @@ -249,6 +247,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),关注后就会发现和「代码随想录」相见恨晚!** -> 我是[程序员Carl](https://github.com/youngyangyang04),更多[精彩算法文章](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),期待你的关注! +**如果感觉对你有帮助,不要吝啬给一个👍吧!** diff --git a/problems/0131.分割回文串.md b/problems/0131.分割回文串.md index 2d72bf1e..ee2e6079 100644 --- a/problems/0131.分割回文串.md +++ b/problems/0131.分割回文串.md @@ -42,7 +42,7 @@ 所以切割问题,也可以抽象为一颗树形结构,如图: - +![131.分割回文串](https://img-blog.csdnimg.cn/20201123203228309.png) 递归用来纵向遍历,for循环用来横向遍历,切割线(就是图中的红线)切割到字符串的结尾位置,说明找到了一个切割方法。 @@ -68,7 +68,7 @@ void backtracking (const string& s, int startIndex) { * 递归函数终止条件 - +![131.分割回文串](https://img-blog.csdnimg.cn/20201123203228309.png) 从树形结构的图中可以看出:切割线切到了字符串最后面,说明找到了一种切割方法,此时就是本层递归的终止终止条件。 @@ -234,5 +234,7 @@ public: **就酱,如果感觉「代码随想录」不错,就把Carl宣传一波吧!** -> 我是[程序员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),关注后就会发现和「代码随想录」相见恨晚!** + +**如果感觉对你有帮助,不要吝啬给一个👍吧!** diff --git a/problems/0216.组合总和III.md b/problems/0216.组合总和III.md index 99e82100..cdcb3aac 100644 --- a/problems/0216.组合总和III.md +++ b/problems/0216.组合总和III.md @@ -1,5 +1,3 @@ -## 链接 -https://leetcode-cn.com/problems/combination-sum-iii/ > 别看本篇选的是组合总和III,而不是组合总和,本题和上一篇[回溯算法:求组合问题!](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)相比难度刚刚好! @@ -36,7 +34,7 @@ https://leetcode-cn.com/problems/combination-sum-iii/ 选取过程如图: - +![216.组合总和III](https://img-blog.csdnimg.cn/20201123195717975.png) 图中,可以看出,只有最后取到集合(1,3)和为4 符合条件。 @@ -98,7 +96,7 @@ if (path.size() == k) { 本题和[回溯算法:求组合问题!](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)区别之一就是集合固定的就是9个数[1,...,9],所以for循环固定i<=9 如图: - +![216.组合总和III](https://img-blog.csdnimg.cn/20201123195717975.png) 处理过程就是 path收集每次选取的元素,相当于树型结构里的边,sum来统计path里元素的总和。 @@ -156,7 +154,7 @@ public: 这道题目,剪枝操作其实是很容易想到了,想必大家看上面的树形图的时候已经想到了。 如图: - +![216.组合总和III1](https://img-blog.csdnimg.cn/2020112319580476.png) 已选元素总和如果已经大于n(图中数值为4)了,那么往后遍历就没有意义了,直接剪掉。 @@ -213,3 +211,8 @@ 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),关注后就会发现和「代码随想录」相见恨晚!** + +**如果感觉对你有帮助,不要吝啬给一个👍吧!** + diff --git a/problems/0332.重新安排行程.md b/problems/0332.重新安排行程.md index 63d8e0c4..a601b2d9 100644 --- a/problems/0332.重新安排行程.md +++ b/problems/0332.重新安排行程.md @@ -221,6 +221,18 @@ public: 一波分析之后,可以看出我就是按照回溯算法的模板来的。 +代码中 +``` +for (pair& target : targets[result[result.size() - 1]]) +``` +pair里要有const,因为map中的key是不可修改的,所以是`pair`。 + +如果不加const,也可以复制一份pair,例如这么写: +``` +for (pairtarget : targets[result[result.size() - 1]]) +``` + + # 总结 本题其实可以算是一道hard的题目了,关于本题的难点我在文中已经列出了。 diff --git a/problems/0452.用最少数量的箭引爆气球.md b/problems/0452.用最少数量的箭引爆气球.md new file mode 100644 index 00000000..e2034bbe --- /dev/null +++ b/problems/0452.用最少数量的箭引爆气球.md @@ -0,0 +1,78 @@ + +# 思路 + +接下来在想一下如何使用最少的弓箭。 + +直觉上来看,貌似只射重叠最多的气球,用的弓箭一定最少,那么有没有当前重叠了三个,我射两个,留下一个和后面的一起射这样弓箭用的更少的情况呢? + +尝试一下举反例,发现没有这种情况,**那么就试一试贪心吧!** + +算法确定下来了,那么如何模拟气球涉爆的过程呢?是在数组中移除元素还是做标记呢? + +如果真实的模拟射气球的过程,应该射一个,气球数组就remove一个元素,这样最直观,毕竟气球被射了。 + +但又想一下,如果把气球排序之后,从前到后遍历气球,被射过的气球仅仅跳过就行了,没有必要让气球数组remove气球,记录一下箭的数量就可以了。 + +> PS:本文[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),关注后就会发现和「代码随想录」相见恨晚! + +以上为思考过程,已经确定下来使用贪心了,那么开始解题。 + +**为了让气球尽可能的重叠,需要对数组进行排序**。 + +那么按照气球起始位置排序,还是按照气球终止位置排序呢? + +其实都可以!只不过对应的遍历顺序不同,我就按照气球的起始位置排序了。 + +既然按照其实位置排序,那么就从前向后遍历气球数组,靠左尽可能让气球重复。 + +从前向后遍历遇到重叠的气球了怎么办? + +如果气球重叠了,重叠气球中右边边界的最小值 之前的区间一定需要一个弓箭。 + +以题目示例: [[10,16],[2,8],[1,6],[7,12]]为例,如图:(方便起见,已经排序) + +![452.用最少数量的箭引爆气球](https://img-blog.csdnimg.cn/20201123101929791.png) + +可以看出首先第一组重叠气球,一定是需要一个箭,气球3,的左边界大于了 第一组重叠气球的最小右边界,所以再需要一支箭来射气球3了。 + +C++代码如下: + +```C++ +class Solution { +private: + static bool cmp(const vector& a, const vector& b) { + return a[0] < b[0]; + } +public: + int findMinArrowShots(vector>& points) { + if (points.size() == 0) return 0; + sort(points.begin(), points.end(), cmp); + + int result = 1; // points 不为空至少需要一支箭 + for (int i = 1; i < points.size(); i++) { + if (points[i][0] > points[i - 1][1]) { // 气球i和气球i-1不挨着,注意这里不是>= + result++; // 需要一支箭 + } + else { // 气球i和气球i-1挨着 + points[i][1] = min(points[i - 1][1], points[i][1]); // 更新重叠气球最小右边界 + } + } + return result; + } +}; +``` + +时间复杂度O(nlogn) +空间复杂度O(1) + +# 注意事项 + +注意题目中说的是:满足 xstart ≤ x ≤ xend,则该气球会被引爆。那么说明两个气球挨在一起不重叠也可以一起射爆, + +所以代码中 `if (points[i][0] > points[i - 1][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/20200815195519696.png),关注后就会发现和「代码随想录」相见恨晚!** + +**如果感觉题解对你有帮助,不要吝啬给一个👍吧!** + diff --git a/problems/0455.分发饼干.md b/problems/0455.分发饼干.md index b1d831f7..1adaf309 100644 --- a/problems/0455.分发饼干.md +++ b/problems/0455.分发饼干.md @@ -1,26 +1,62 @@ +> 贪心的第一道题目,快看看你够不够贪心 -## 链接 +通知:一些录友表示经常看不到每天的文章,现在公众号已经不按照发送时间推荐了,而是根据一些规则乱序推送,所以可能关注了「代码随想录」也一直看不到文章,建议把「代码随想录」设置星标哈,设置星标之后,每天就按发文时间推送了,我每天都是定时8:35发送的,嗷嗷准时! + +# 455.分发饼干 + +题目链接:https://leetcode-cn.com/problems/assign-cookies/ + +假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 + +对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。 + +示例 1: +输入: g = [1,2,3], s = [1,1] +输出: 1 +解释: +你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。 +虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。 +所以你应该输出1。 + +示例 2: +输入: g = [1,2], s = [1,2,3] +输出: 2 +解释: +你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。 +你拥有的饼干数量和尺寸都足以让所有孩子满足。 +所以你应该输出2. +  + +提示: +* 1 <= g.length <= 3 * 104 +* 0 <= s.length <= 3 * 104 +* 1 <= g[i], s[j] <= 231 - 1 -https://leetcode-cn.com/problems/assign-cookies/ ## 思路 -这道题目呢,其实可以用较大大的饼干优先满足可以满足的胃口大的小孩。 +为了了满足更多的小孩,就不要造成饼干尺寸的浪费。 -注意我这里用的是 可以满足的胃口大的小孩。这样就不会造成大饼干的浪费。 +大尺寸的饼干既可以满足胃口大的孩子也可以满足胃口小的孩子,那么就应该优先满足胃口大的。 -所以使用贪心策略,讲饼干数组和小孩数组排序。 +**这里的局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩**。 -然后从后向前遍历小孩数组,用大饼干优先满足胃口大的,并统计满足小孩数量的大小就可以了。 +可以尝试使用贪心策略,先将饼干数组和小孩数组排序。 + +然后从后向前遍历小孩数组,用大饼干优先满足胃口大的,并统计满足小孩数量。 如图: - +![455.分发饼干](https://img-blog.csdnimg.cn/20201123161809624.png) + +这个例子可以看出饼干9只有喂给胃口为7的小孩,这样才是整体最优解,并想不出反例,那么就可以撸代码了。 C++代码整体如下: ``` +// 时间复杂度:O(nlogn) +// 空间复杂度:O(1) class Solution { public: int findContentChildren(vector& g, vector& s) { @@ -38,5 +74,18 @@ public: } }; ``` + +从代码中可以看出我用了一个index来控制饼干数组的遍历,遍历饼干并没有再起一个for循环,而是采用自减的方式,这也是常用的技巧。 + +有的同学看到要遍历两个数组,就想到用两个for循环,那样逻辑其实就复杂了。 + +# 总结 + +这道题是贪心很好的一道入门题目,思路还是比较容易想到的。 + +文中详细介绍了思考的过程,**想清楚局部最优,想清楚全局最优,感觉局部最优是可以推出全局最优,并想不出反例,那么就试一试贪心**。 + +就酱,「代码随想录」值得介绍给身边的朋友同学们! + > 我是[程序员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),期待你的关注! diff --git a/problems/1049.最后一块石头的重量II.md b/problems/1049.最后一块石头的重量II.md new file mode 100644 index 00000000..3fd745bd --- /dev/null +++ b/problems/1049.最后一块石头的重量II.md @@ -0,0 +1,24 @@ + +// 如何转化为01背包问题 + +尽量让石头分成,重量相同的两堆,这样就化解成 01背包问题了。 + +``` +class Solution { +public: + int lastStoneWeightII(vector& stones) { + vector dp(30001, 0); + int sum = 0; + for (int i = 0; i < stones.size(); i++) sum += stones[i]; + int target = sum / 2; + for (int i = 0; i < stones.size(); i++) { + for (int j = target; j >= 0; j--) { + if (j - stones[i] >= 0) { + dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]); + } + } + } + return sum - dp[target] - dp[target]; + } +}; +``` diff --git a/problems/回溯算法理论基础.md b/problems/回溯算法理论基础.md index 5ec03f2b..d3581599 100644 --- a/problems/回溯算法理论基础.md +++ b/problems/回溯算法理论基础.md @@ -154,4 +154,7 @@ void backtracking(参数) { 今天是回溯算法的第一天,按照惯例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),关注后就会发现和「代码随想录」相见恨晚!** + +**如果感觉对你有帮助,不要吝啬给一个👍吧!**