前言
自己之前也是在简书写文章,后来发现了 SegmentFault ,感觉挺不错的,写作和阅读方面比简书要方便得多,所以决定来试一下,之前也写过类似 OJ专题 系列文章,从今天开始准备迁移过来,好了下面开始正文
LeetCode 中股票系列问题,前两题较容易,后两题难度远高于前两题,类型差不多,也是在网上大牛的参考下,才得以解决和消化,以下为系列四题的解题思路,并附上算法源码 GitHub 17/05/20
Best Time to Buy and Sell Stock I (Eazy)
问题描述
给出一段股票行情记录,现在可以进行一次买卖交易,求利润最大值
Examples
Input
[7, 1, 5, 3, 6, 4]
Output
The answer is 6 - 1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price)
算法思路
从头买入,遍历卖出点
若利润小于零,则可认为该点比旧买入点更小,应该重新从该点买入
若利润大于历史最高利润,则记录最高利润
AC 代码
int maxProfit(vector<int>& prices) {
if (prices.size() == 0) {
return 0;
}
int max = 0;
int start = 0;
for (int i = 0; i < prices.size(); i++) {
int dif = prices[i] - prices[start];
if (dif <= 0) {
start = i;
} else {
if (dif > max) {
max = dif;
}
}
}
return max;
}
Best Time to Buy and Sell Stock II (Eazy)
问题描述
给出一段股票行情记录,不限制交易次数,求利润最大值
算法思路
利用贪心思想,每天都买入卖出,最终局部最优解之和则为全局最优解
AC 代码
int maxProfit(vector<int>& prices) {
if (prices.size() == 0) {
return 0;
}
int sum = 0;
for (int i = 1; i < prices.size(); i++) {
if (prices[i] - prices[i - 1] > 0) {
sum += prices[i] - prices[i - 1];
}
}
return sum;
}
Best Time to Buy and Sell Stock III (Hard)
问题描述
给出一段股票行情记录,现在至多可进行两次买卖交易,求利润最大值
算法思路
该题和第四题是一样的,见问题 IV
Best Time to Buy and Sell Stock IV (Hard)
问题描述
给出一段股票行情记录,现在至多可进行 k 次买卖交易,求利润最大值
Examples
Input
2
[7, 1, 5, 3, 6, 4]
Output
(5 - 1) + (6 - 3) = 7
算法思路
这题也是参考了网上大神们的思想,这种解法并不关心你的 k 次交易是从哪天买入和卖出的,只关心 今天的利润 和 以往的最高利润 到底哪个利润大,此处要设两个 DP 变量:
局部最高利润:从 i0 天到 i 天,并在 i 天卖出的最高利润
全局最高利润:从 i0 天到 i 天的最高利润
DP
一天一天遍历
-
局部最高利润有两种可能
要么是 今天的利润 与 昨天的局部最高利润 之和
要么是 今天的利润 与 昨天的全局最高利润 之和
-
全局最高利润也有两种可能
要么是 昨天的全局最高利润
要么是 今天的局部最高利润
Hint
LeetCode 的 OJ 提供的校验数据中,有故意将 k 设置成很大,而天数又很小的测验数据,因此在这里需要优化,否则将报出 RuntimeException
当 k 很大时,也就相当于问题 II,可以买无数次,利用之前的贪心解法就能 AC 了
AC 代码
int maxProfit(int k, vector<int> &prices) {
if (prices.empty()) {
return 0;
}
if (k >= prices.size()) {
return solveMaxProfit(prices);
}
int g[k + 1] = {0};
int l[k + 1] = {0};
for (int i = 0; i < prices.size() - 1; ++i) {
int diff = prices[i + 1] - prices[i];
for (int j = k; j >= 1; --j) {
l[j] = max(g[j - 1] + max(diff, 0), l[j] + diff);
g[j] = max(g[j], l[j]);
}
}
return g[k];
}
int solveMaxProfit(vector<int> &prices) {
int res = 0;
for (int i = 1; i < prices.size(); ++i) {
if (prices[i] - prices[i - 1] > 0) {
res += prices[i] - prices[i - 1];
}
}
return res;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。