LeetCode: Best Time to Buy and Sell Stock I && II && III
Title:
Say you have an array for which the ith 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.
思路:对于ith个,找出之前的最小值,然后用当前的减去最小值,看是否是最大的利润。实际上就是动态规划
dp[i] = max{dp[i-1], prices[i] - minprices} ,minprices是区间[0,1,2...,i-1]内的最低价格
class Solution { public: int maxProfit(vector<int>& prices) { if (prices.size() < 2) return 0; int min_price = prices[0]; int profit = 0; for (int i = 1; i < prices.size(); i++){ min_price = min(min_price,prices[i-1]); profit = max(profit,prices[i]-min_price); } return profit; } };
按照股票差价构成新数组 prices[1]-prices[0], prices[2]-prices[1], prices[3]-prices[2], ..., prices[n-1]-prices[n-2]。求新数组的最大子段和就是我们求得最大利润,假设最大子段和是从新数组第 i 到第 j 项,那么子段和= prices[j]-prices[j-1]+prices[j-1]-prices[j-2]+...+prices[i]-prices[i-1] = prices[j]-prices[i-1], 即prices[j]是最大价格,prices[i-1]是最小价格,且他们满足前后顺序关系。
class Solution { public: int maxProfit(vector<int> &prices) { // IMPORTANT: Please reset any member data you declared, as // the same Solution instance will be reused for each test case. int len = prices.size(); if(len <= 1)return 0; int res = 0, currsum = 0; for(int i = 1; i < len; i++) { if(currsum <= 0) currsum = prices[i] - prices[i-1]; else currsum += prices[i] - prices[i-1]; if(currsum > res) res = currsum; } return res; } };
Title:
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 as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
思路 (1): 我开始的思路就是找出每个递增子序列
class Solution { public: int maxProfit(vector<int>& prices) { if (prices.size() < 2) return 0; int first = prices[0]; for (int i = 1; i < prices.size(); i++){ if (prices[i] > first){ while(++i < prices.size()){ if (prices[i] < prices[i-1]) break; } vector<int> v(prices.begin()+i,prices.end()); return prices[i-1]-first + maxProfit(v); }else{ first = prices[i]; } } return 0; } };
思路(2):还是将原始序列变换成间隔,然后只要将为正的间隔加和就可以了
class Solution { public: int maxProfit(vector<int>& prices) { if (prices.size() < 2) return 0; int profit = 0; for (int i = 1; i < prices.size(); i++){ int gap = prices[i] - prices[i-1]; if (gap > 0) profit += gap; } return profit; } };
Title:
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.
思路:
分析:这一题约束最多只能买卖两次股票,并且手上最多也只能持有一支股票。因为不能连续买入两次股票,所以买卖两次肯定分布在前后两个不同的区间。设p(i) = 区间[0,1,2...i]的最大利润 + 区间[i,i+1,....n-1]的最大利润(式子中两个区间内分别只能有一次买卖,这就是第一道题的问题),那么本题的最大利润 = max{p[0],p[1],p[2],...,p[n-1]}。根据第一题的算法2,我们可以求区间[0,1,2...i]的最大利润;同理可以从后往前扫描数组求区间[i,i+1,....n-1]的最大利润,其递归式如下:
dp[i-1] = max{dp[i], maxprices - prices[i-1]} ,maxprices是区间[i,i+1,...,n-1]内的最高价格。
class Solution { public: int maxProfit(vector<int>& prices) { int size = prices.size(); if (size < 2) return 0; vector<int> left(size,0); int min_price = INT_MAX; int cur_right = 0; for (int i = 1; i < size; i++){ min_price = min(min_price,prices[i-1]); left[i] = max(left[i-1],prices[i]-min_price); } int result = left[size-1]; int max_price = INT_MIN; for (int i = size-2; i >= 0; i--){ max_price = max(max_price,prices[i+1]); cur_right = max(cur_right,max_price-prices[i]); result = max(result,left[i]+cur_right); } return result; } };