1. 题目描述
Say you have an array for which the i element is the price of a given stock on day i.If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.
【翻译过来】:给定了一个数组,代表每一天股票的价格。现在是只允许买卖一次,设计一个算法能够计算出通过什么时候买卖可以获得最大的利润。
2. 样例
【example1】:
Input: [7, 1, 5, 3, 6, 4]
Output: 5
max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price)
【example2】:
Input: [7, 6, 4, 3, 1]
Output: 0
In this case, no transaction is done, i.e. max profit = 0.
3. 分析
这道题和之前写的一篇博文类型相似,都是设计算法能够找到最优的买卖股票的算法,从而能够获得最大的利润,与之前不同的是,这里只允许一次买卖。
我们分析一下不难发现,想要求得结果,需要满足以下条件:
- 买入股票的天应当小于卖出股票的天,即需要先买再卖;
- 最开始的利润profit是0,代表既没有买也没有卖;
- 同理,最开始的buyDay和sellDay也是0;
- 遍历数组,如果当前天i的价格高于buyDay的价格,说明可以考虑卖出当天股票,转入下一步;
- 如果当前天的价格与buyDay的价格差高于profit,说明在这一天卖出可以有更高的利润,profit改为此差值,将i赋值给sellDay;
- 否则说明虽然在这一天卖出能够赚的利润,但是不如之前的某一次交易利润高。不做任何事情;
- 如果当前天i的价格低于buyDay的价格,说明其实可以在这一天购买股票,将i赋值给buyDay;
【核心思想】:动态规划的思想,找出当前的最大利润值。
【注意的问题】:需要注意的是,给出了数组说明我们事先可以选择在什么时候购买什么时候出售,所以和现实生活中情况是不同的,一定不要钻牛角尖。
4. 源码
class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.size() <= 1) {
return 0;
}
int profit = 0;
int buyDay = 0;
int sellDay = 0;
for (int i = 1; i < (int)prices.size(); i++) {
if (prices[i] - prices[buyDay] > 0) {
if (prices[i] - prices[buyDay] > profit) {
profit = prices[i] - prices[buyDay];
sellDay = i;
}
}
else {
buyDay = i;
}
}
return profit;
}
};
5. 心得
动态规划的简单题目,能够理解:我们在遍历的过程中可以随时选择在什么时候购买什么出售股票这个前提,就可以轻易解题了。