Skip to content

Commit 9f6e4e9

Browse files
Update
1 parent 77f45df commit 9f6e4e9

File tree

4 files changed

+144
-11
lines changed

4 files changed

+144
-11
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
* [BAT级别技术面试流程和注意事项都在这里了](https://mp.weixin.qq.com/s/815qCyFGVIxwut9I_7PNFw)
4848
* [深圳原来有这么多互联网公司,你都知道么?](https://mp.weixin.qq.com/s/Yzrkim-5bY0Df66Ao-hoqA)
4949
* [北京有这些互联网公司,你都知道么?](https://mp.weixin.qq.com/s/FQTzoZtqXQ2rlS1UthGrag)
50+
* [上海有这些互联网公司,你都知道么?](https://mp.weixin.qq.com/s/msqbX6eR2-JBQOYFfec4sg)
5051

5152
* 算法性能分析
5253
* [究竟什么是时间复杂度,怎么求时间复杂度,看这一篇就够了](https://mp.weixin.qq.com/s/lYL9TSxLqCeFXIdjt4dcIw)
@@ -123,8 +124,7 @@
123124
* [二叉树:一入递归深似海,从此offer是路人](https://mp.weixin.qq.com/s/PwVIfxDlT3kRgMASWAMGhA)
124125
* [二叉树:听说递归能做的,栈也能做!](https://mp.weixin.qq.com/s/c_zCrGHIVlBjUH_hJtghCg)
125126
* [二叉树:前中后序迭代方式的写法就不能统一一下么?](https://mp.weixin.qq.com/s/WKg0Ty1_3SZkztpHubZPRg)
126-
* [二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/Gb3BjakIKGNpup2jYtTzog)
127-
* [二叉树:你真的会翻转二叉树么?](https://mp.weixin.qq.com/s/6gY1MiXrnm-khAAJiIb5Bg)
127+
* [二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/Gb3BjakIKGNpup2jYtTzog) * [二叉树:你真的会翻转二叉树么?](https://mp.weixin.qq.com/s/6gY1MiXrnm-khAAJiIb5Bg)
128128
* [本周小结!(二叉树)](https://mp.weixin.qq.com/s/JWmTeC7aKbBfGx4TY6uwuQ)
129129
* [二叉树:我对称么?](https://mp.weixin.qq.com/s/Kgf0gjvlDlNDfKIH2b1Oxg)
130130
* [二叉树:看看这些树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg)
@@ -175,6 +175,7 @@
175175
* [本周小结!(回溯算法系列三)](https://mp.weixin.qq.com/s/tLkt9PSo42X60w8i94ViiA)
176176
* [本周小结!(回溯算法系列三)续集](https://mp.weixin.qq.com/s/kSMGHc_YpsqL2j-jb_E_Ag)
177177
* [视频来了!!带你学透回溯算法(理论篇)](https://mp.weixin.qq.com/s/wDd5azGIYWjbU0fdua_qBg)
178+
* [视频来了!!回溯算法:组合问题](https://mp.weixin.qq.com/s/a_r5JR93K_rBKSFplPGNAA)
178179
* [回溯算法:重新安排行程](https://mp.weixin.qq.com/s/3kmbS4qDsa6bkyxR92XCTA)
179180
* [回溯算法:N皇后问题](https://mp.weixin.qq.com/s/lU_QwCMj6g60nh8m98GAWg)
180181
* [回溯算法:解数独](https://mp.weixin.qq.com/s/eWE9TapVwm77yW9Q81xSZQ)
@@ -315,6 +316,7 @@
315316
|[0454.四数相加II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0454.四数相加II.md) |哈希表 |中等| **哈希**|
316317
|[0455.分发饼干](https://github.com/youngyangyang04/leetcode/blob/master/problems/0455.分发饼干.md) |贪心 |简单| **贪心**|
317318
|[0459.重复的子字符串](https://github.com/youngyangyang04/leetcode/blob/master/problems/0459.重复的子字符串.md) |字符创 |简单| **KMP**|
319+
|[0474.一和零](https://github.com/youngyangyang04/leetcode/blob/master/problems/0474.一和零.md) |动态规划 |中等| **多重背包** 好题目|
318320
|[0486.预测赢家](https://github.com/youngyangyang04/leetcode/blob/master/problems/0486.预测赢家.md) |动态规划 |中等| **递归** **记忆递归** **动态规划**|
319321
|[0491.递增子序列](https://github.com/youngyangyang04/leetcode/blob/master/problems/0491.递增子序列.md) |深度优先搜索 |中等|**深度优先搜索/回溯算法** 这个去重有意思|
320322
|[0496.下一个更大元素I](https://github.com/youngyangyang04/leetcode/blob/master/problems/0496.下一个更大元素I.md) ||中等|**单调栈** 入门题目,但是两个数组还是有点绕的|
Lines changed: 106 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,79 @@
1-
## 链接
2-
https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/
1+
> 贪心有时候比动态规划更巧妙,更好用!
32
4-
## 思路
3+
# 122.买卖股票的最佳时机II
54

6-
首先要知道第0天买入,第3天卖出的利润:prices[3] - prices[0],相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + ()prices[1] - prices[0])
5+
题目链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/
76

8-
那么根据prices可以得到每天的利润序列:(prices[i] - prices[i - 1]).....(prices[1] - prices[0])。
7+
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
8+
9+
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
10+
11+
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
12+
13+
14+
示例 1:
15+
输入: [7,1,5,3,6,4]
16+
输出: 7
17+
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4。随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
18+
19+
示例 2:
20+
输入: [1,2,3,4,5]
21+
输出: 4
22+
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
23+
24+
示例 3:
25+
输入: [7,6,4,3,1]
26+
输出: 0
27+
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
28+
29+
提示:
30+
* 1 <= prices.length <= 3 * 10 ^ 4
31+
* 0 <= prices[i] <= 10 ^ 4
32+
33+
# 思路
34+
35+
本题首先要清楚两点:
36+
37+
* 只有一只股票!
38+
* 当前只有买股票或者买股票的操作
939

10-
可以发现,我们需要收集每天的正利润就可以,收集正利润的区间,就是股票买卖的区间,而我们只需要关注最终利润就可以了,不需要记录区间
40+
想获得利润至少要两天为一个交易单元
1141

12-
**这就是贪心所贪的地方,只收集正利润**
42+
## 贪心算法
43+
44+
这道题目可能我们只会想,选一个低的买入,在选个高的卖,在选一个低的买入.....循环反复。
45+
46+
**如果想到其实最终利润是可以分解的,那么本题就很容易了!**
47+
48+
如果分解呢?
49+
50+
假如第0天买入,第3天卖出,那么利润为:prices[3] - prices[0]
51+
52+
相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。
53+
54+
**此时就是把利润分解为每天为单位的维度,而不是从0天到第3天整体去考虑!**
55+
56+
那么根据prices可以得到每天的利润序列:(prices[i] - prices[i - 1]).....(prices[1] - prices[0])。
1357

1458
如图:
1559

16-
<img src='../pics/122.买卖股票的最佳时机II.png' width=600> </img></div>
60+
![122.买卖股票的最佳时机II](https://img-blog.csdnimg.cn/2020112917480858.png)
61+
62+
一些同学陷入:第一天怎么就没有利润呢,第一天到底算不算的困惑中。
63+
64+
第一天当然没有利润,至少要第二天才会有利润,所以利润的序列比股票序列少一天!
65+
66+
从图中可以发现,其实我们需要收集每天的正利润就可以,**收集正利润的区间,就是股票买卖的区间,而我们只需要关注最终利润,不需要记录区间**
67+
68+
那么只收集正利润就是贪心所贪的地方!
69+
70+
**局部最优:收集每天的正利润,全局最优:求得最大利润**
71+
72+
局部最优可以推出全局最优,找不出反例,试一试贪心!
1773

1874
对应C++代码如下:
1975

20-
```
76+
```C++
2177
class Solution {
2278
public:
2379
int maxProfit(vector<int>& prices) {
@@ -29,6 +85,47 @@ public:
2985
}
3086
};
3187
```
88+
* 时间复杂度O(n)
89+
* 空间复杂度O(1)
90+
91+
## 动态规划
92+
93+
动态规划将在下一个系列详细讲解,本题解先给出我的C++代码(带详细注释),感兴趣的同学可以自己先学习一下。
94+
95+
```C++
96+
class Solution {
97+
public:
98+
int maxProfit(vector<int>& prices) {
99+
// dp[i][1]第i天持有的最多现金
100+
// dp[i][0]第i天持有股票后的最多现金
101+
int n = prices.size();
102+
vector<vector<int>> dp(n, vector<int>(2, 0));
103+
dp[0][0] -= prices[0]; // 持股票
104+
for (int i = 1; i < n; i++) {
105+
// 第i天持股票所剩最多现金 = max(第i-1天持股票所剩现金, 第i-1天持现金-买第i天的股票)
106+
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
107+
// 第i天持有最多现金 = max(第i-1天持有的最多现金,第i-1天持有股票的最多现金+第i天卖出股票)
108+
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
109+
}
110+
return max(dp[n - 1][0], dp[n - 1][1]);
111+
}
112+
};
113+
```
114+
* 时间复杂度O(n)
115+
* 空间复杂度O(n)
116+
117+
# 总结
118+
119+
股票问题其实是一个系列的,属于动态规划的范畴,因为目前在讲解贪心系列,所以股票问题会在之后的动态规划系列中详细讲解。
120+
121+
**可以看出有时候,贪心往往比动态规划更巧妙,更好用,所以别小看了贪心算法**
122+
123+
**本题中理解利润拆分是关键点!** 不要整块的去看,而是把整体利润拆为每天的利润。
124+
125+
一旦想到这里了,很自然就会想到贪心了,即:只收集每天的正利润,最后稳稳的就是最大利润了。
126+
127+
就酱,「代码随想录」是技术公众号里的一抹清流,值得推荐给你的朋友同学们!
128+
32129

33130
> 我是[程序员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),期待你的关注!
34131

problems/0300.最长上升子序列.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11

2+
## 思路
23
* dp[i]的定义
34

45
dp[i]表示i之前包括i的最长上升子序列。
@@ -11,6 +12,7 @@ dp[i]表示i之前包括i的最长上升子序列。
1112

1213
* 状态转移方程
1314

15+
位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 + 1 的最大值。
1416

1517
if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);
1618

problems/0474.一和零.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
搞不懂 leetcode后台是什么牛逼的编译器,初始化int dp[101][101] = {0}; 可以 ,int dp[101][101];就不行,有其他默认值,坑死。
3+
代码我做了实验,后台会拿findMaxForm,运行两次,取第二次的结果,dp有上次记录的数值。
4+
5+
```
6+
// 即使做了很多动态规划的题目,做这个依然懵逼
7+
// 这道题目有点 程序员自己给自己出难进急转弯的意思
8+
// 该子集中 最多 有 m 个 0 和 n 个 1 。 指的是整体子集
9+
// 这是二维背包,多重背包
10+
// dp[i][j] 有i个0,j个1最大有多少个子集,但是遍历的时候 顶部是哪里呢?
11+
class Solution {
12+
public:
13+
int findMaxForm(vector<string>& strs, int m, int n) {
14+
int dp[101][101] = {0}; // 默认初始化0
15+
for (int i = 0; i < strs.size(); i++) {
16+
int oneNum = 0, zeroNum = 0;
17+
for (char c : strs[i]) {
18+
if (c == '0') zeroNum++;
19+
else oneNum++;
20+
}
21+
// 果然还是从后向前,模拟01背包
22+
for (int j = m; j >= zeroNum; j--) {
23+
for (int k = n; k >= oneNum; k--) {
24+
dp[j][k] = max(dp[j][k], dp[j - zeroNum][k - oneNum] + 1);
25+
}
26+
}
27+
}
28+
return dp[m][n];
29+
}
30+
};
31+
32+
```

0 commit comments

Comments
 (0)