mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-06 07:06:42 +08:00
Update
This commit is contained in:
@ -340,6 +340,7 @@
|
||||
|[0113.路径总和II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0113.路径总和II.md) |二叉树树 |简单|**深度优先搜索/递归** **回溯** **栈**|
|
||||
|[0116.填充每个节点的下一个右侧节点指针](https://github.com/youngyangyang04/leetcode/blob/master/problems/0116.填充每个节点的下一个右侧节点指针.md) |二叉树 |中等|**递归** **迭代/广度优先搜索**|
|
||||
|[0117.填充每个节点的下一个右侧节点指针II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0117.填充每个节点的下一个右侧节点指针II.md) |二叉树 |中等|**递归** **迭代/广度优先搜索**|
|
||||
|[0122.买卖股票的最佳时机II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0122.买卖股票的最佳时机II.md) |贪心 |简单|**贪心** |
|
||||
|[0127.单词接龙](https://github.com/youngyangyang04/leetcode/blob/master/problems/ 0127.单词接龙.md) |广度优先搜索 |中等|**广度优先搜索**|
|
||||
|[0129.求根到叶子节点数字之和](https://github.com/youngyangyang04/leetcode/blob/master/problems/0129.求根到叶子节点数字之和.md) |二叉树 |中等|**递归/回溯** 递归里隐藏着回溯,和113.路径总和II类似|
|
||||
|[0131.分割回文串](https://github.com/youngyangyang04/leetcode/blob/master/problems/0131.分割回文串.md) |回溯 |中等|**回溯**|
|
||||
|
BIN
pics/122.买卖股票的最佳时机II.png
Normal file
BIN
pics/122.买卖股票的最佳时机II.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
Binary file not shown.
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 172 KiB |
BIN
pics/90.子集II.png
BIN
pics/90.子集II.png
Binary file not shown.
Before Width: | Height: | Size: 235 KiB After Width: | Height: | Size: 292 KiB |
@ -1,13 +1,15 @@
|
||||
# 题目地址
|
||||
https://leetcode-cn.com/problems/subsets-ii/
|
||||
|
||||
# 第90题. 子集II
|
||||
> 子集问题加去重!
|
||||
|
||||
# 第90题.子集II
|
||||
|
||||
题目链接:https://leetcode-cn.com/problems/subsets-ii/
|
||||
|
||||
给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
|
||||
|
||||
说明:解集不能包含重复的子集。
|
||||
|
||||
示例:
|
||||
示例:
|
||||
输入: [1,2,2]
|
||||
输出:
|
||||
[
|
||||
@ -22,56 +24,65 @@ https://leetcode-cn.com/problems/subsets-ii/
|
||||
|
||||
# 思路
|
||||
|
||||
这道题目和[0078.子集](https://github.com/youngyangyang04/leetcode/blob/master/problems/0078.子集.md)区别就是集合里有重复元素了,而且求取的子集要去重。
|
||||
做本题之前一定要先做[78.子集](https://mp.weixin.qq.com/s/NNRzX-vJ_pjK4qxohd_LtA)。
|
||||
|
||||
很多同学在去重上想不明白,其实很多题解也没有讲清楚,反正代码是能过的,感觉是那么回事,稀里糊涂的先把题目过了。
|
||||
这道题目和[回溯算法:求子集问题!](https://mp.weixin.qq.com/s/NNRzX-vJ_pjK4qxohd_LtA)区别就是集合里有重复元素了,而且求取的子集要去重。
|
||||
|
||||
这个去重为什么很难理解呢,**所谓去重,其实就是使用过的元素不能重复选取。** 这么一说好像很简单!
|
||||
那么关于回溯算法中的去重问题,**在[40.组合总和II](https://mp.weixin.qq.com/s/_1zPYk70NvHsdY8UWVGXmQ)中已经详细讲解过了,和本题是一个套路**。
|
||||
|
||||
都知道组合问题可以抽象为树形结构,那么“使用过”在这个树形结构上是有两个维度的,一个维度是同一树枝上使用过,一个维度是同一树层上使用过。**没有理解这两个层面上的“使用过” 是造成大家没有彻底理解去重的根本原因。**
|
||||
**剧透一下,后期要讲解的排列问题里去重也是这个套路,所以理解“树层去重”和“树枝去重”非常重要**。
|
||||
|
||||
所以要明确我们要去重的是同一树层上的“使用过”。
|
||||
|
||||
**还要强调的是去重一定要对元素经行排序,这样我们才方便通过相邻的节点来判断是否重复使用了。**
|
||||
|
||||
用示例中的[1, 2, 2] 来举例,如图所示:
|
||||
用示例中的[1, 2, 2] 来举例,如图所示: (**注意去重需要先对集合排序**)
|
||||
|
||||
<img src='../pics/90.子集II.png' width=600> </img></div>
|
||||
|
||||
从图中可以看出,同一树层上对重复取2 就要过滤掉,同一树枝上就可以重复取2,因为同一树枝上元素的集合才是唯一子集!
|
||||
从图中可以看出,同一树层上重复取2 就要过滤掉,同一树枝上就可以重复取2,因为同一树枝上元素的集合才是唯一子集!
|
||||
|
||||
代码如下:(已经详细注释)
|
||||
本题就是其实就是[回溯算法:求子集问题!](https://mp.weixin.qq.com/s/NNRzX-vJ_pjK4qxohd_LtA)的基础上加上了去重,去重我们在[回溯算法:求组合总和(三)](https://mp.weixin.qq.com/s/_1zPYk70NvHsdY8UWVGXmQ)也讲过了,所以我就直接给出代码了:
|
||||
|
||||
# C++代码
|
||||
|
||||
```
|
||||
class Solution {
|
||||
private:
|
||||
void backtracking(vector<int>& nums, vector<vector<int>>& result, vector<int>& vec, int startIndex, vector<bool>& used) {
|
||||
result.push_back(vec);
|
||||
vector<vector<int>> result;
|
||||
vector<int> path;
|
||||
void backtracking(vector<int>& nums, int startIndex, vector<bool>& used) {
|
||||
result.push_back(path);
|
||||
for (int i = startIndex; i < nums.size(); i++) {
|
||||
// used[i - 1] == true,说明同一树支candidates[i - 1]使用过
|
||||
// used[i - 1] == true,说明同一树支candidates[i - 1]使用过
|
||||
// used[i - 1] == false,说明同一树层candidates[i - 1]使用过
|
||||
// 而我们要对同一树层使用过的元素进行跳过
|
||||
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {
|
||||
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {
|
||||
continue;
|
||||
}
|
||||
vec.push_back(nums[i]);
|
||||
path.push_back(nums[i]);
|
||||
used[i] = true;
|
||||
backtracking(nums, result, vec, i + 1, used);
|
||||
backtracking(nums, i + 1, used);
|
||||
used[i] = false;
|
||||
vec.pop_back();
|
||||
path.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
|
||||
result.clear();
|
||||
path.clear();
|
||||
vector<bool> used(nums.size(), false);
|
||||
vector<vector<int>> result;
|
||||
vector<int> vec;
|
||||
sort(nums.begin(), nums.end());
|
||||
backtracking(nums, result, vec, 0, used);
|
||||
sort(nums.begin(), nums.end()); // 去重需要排序
|
||||
backtracking(nums, 0, used);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
# 总结
|
||||
|
||||
其实这道题目的知识点,我们之前都讲过了,如果之前讲过的子集问题和去重问题都掌握的好,这道题目应该分分钟AC。
|
||||
|
||||
**就酱,如果感觉融会贯通了,就把「代码随想录」介绍给自己的同学朋友吧,也许他们也需要!**
|
||||
|
||||
> 我是[程序员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),期待你的关注!
|
||||
|
||||
|
||||
|
34
problems/0122.买卖股票的最佳时机II.md
Normal file
34
problems/0122.买卖股票的最佳时机II.md
Normal file
@ -0,0 +1,34 @@
|
||||
## 链接
|
||||
https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/
|
||||
|
||||
## 思路
|
||||
|
||||
首先要知道第0天买入,第3天卖出的利润:prices[3] - prices[0],相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + ()prices[1] - prices[0])
|
||||
|
||||
那么根据prices可以得到每天的利润序列:(prices[i] - prices[i - 1]).....(prices[1] - prices[0])。
|
||||
|
||||
可以发现,我们需要收集每天的正利润就可以,收集正利润的区间,就是股票买卖的区间,而我们只需要关注最终利润就可以了,不需要记录区间。
|
||||
|
||||
**这就是贪心所贪的地方,只收集正利润**。
|
||||
|
||||
如图:
|
||||
|
||||
<img src='../pics/122.买卖股票的最佳时机II.png' width=600> </img></div>
|
||||
|
||||
对应C++代码如下:
|
||||
|
||||
```
|
||||
class Solution {
|
||||
public:
|
||||
int maxProfit(vector<int>& prices) {
|
||||
int result = 0;
|
||||
for (int i = 1; i < prices.size(); i++) {
|
||||
result += max(prices[i] - prices[i - 1], 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
> 我是[程序员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),期待你的关注!
|
||||
|
Reference in New Issue
Block a user