之前刷题觉得没什么动力,因为觉得找工作还那么远呢...但是因为自己水平不咋地,现在不开始积累等到需要的时候就迟了,所以这个星期又开始努力刷题...
这一个星期刷的题比我之前几个月做的加起来都多,但是都没有写博客,这星期接下来的工作就是把题目整理一下吧。前段时间也做了一些题,但是挺多都没有自己的想法,参考了网上的答案,所以就没有写到博客上来。今天翻看之前的博客时,看到自己有记录完全靠自己做出一道题的开心,其实今天也有这样的心情,我觉得收获还是挺多的,所以决定以后还是把做过的题记录到博客上来,一来,不会做的题我可以做个笔记,二来,我自己做出来的题会让我比较有成就感,比较有动力去做后面的题目。
顺便,今天leetcode做了50题了,1/3了呢~还是有点小激动的哇~~
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most two transactions.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
题目地址:https://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/
这里要求出买卖股票的最大收益,而且你最多可以买两次股票
后面有一道题也是要求最大收益,区别是你最多只可以进行一次交易
先考虑只进行一次交易的情况:
那就是找出数组中相差最大的两个数,最简单的方法是对于一个数计算所有它后面的数和它的差,然后所有差中最大的那个就是我们要求的,这时的时间复杂度是o(n^2).
这里有一个O(N)的解法(参考了别人的答案)。我们可以遍历一次数据,用min来记录遍历过的所有元素中的最小值,用max记录遍历过的数据中的最大的profit。最后的max就是我们要的答案。
这是一次交易的情况。两次交易的情况下,我们可以一次正面扫描数组求最大收益max1,一次从数组后面还是扫描求最大亏损(其实就是正面扫描情况下的最大收益)max2,max1+max2最大时就是我们要的答案。
代码:
class Solution {
public:
int maxProfit(vector<int> &prices) {
//最多交易两次
//根据Best Time to Buy and Sell Stock这一题的思想,可以正面扫描一次数组求出在第i天之前能取得的最大收益
//然后反向扫描一遍数组求出第i天之后能取得的最大收益
//然后两者之和的最大值就是我们的最大收益
int len = prices.size();
vector<int> profitB(len),profitA(len);
//第一遍扫描,求出第i天之前的最大收益
int min = INT_MAX,maxP = 0;
for(int i = 0;i < prices.size();i++){
min = prices[i] < min ? prices[i] : min;
int p = prices[i] - min;
maxP = p > maxP ? p : maxP;
profitB[i] = maxP;
}
//第二遍扫描,求出第i天之后的最大收益
//从第i天到第n天的最大收益,就是第n天到第i的最大亏损
int maxPrice= INT_MIN;
maxP = 0;
for(int i = prices.size() - 1;i >= 0;i--){
maxPrice = prices[i] > maxPrice ? prices[i] : maxPrice;
int p = maxPrice - prices[i];
maxP = p > maxP ? p : maxP;
profitA[i] = maxP;
}
//第三遍扫描,求最大收益
int max = 0,sum = 0;
for(int i = 0;i < prices.size();i++){
sum = profitB[i] + profitA[i];
max = sum > max ? sum : max;
}
return max;
}
};