LeetCode—121. Best Time to Buy and Sell Stock
题目
股票售卖问题。给出一个数组,其中第i个元素代表第i天这支股票的价格。现在要求买进股票,然后卖出。求出最大的收益。
思路及解法
这道题是三道股票售卖题目的第一道。
第一种方法,我们可以将问题转化为最大子串和的问题,这样可以借鉴53. Maximum Subarray其中的方法。具体怎么转化,是将股票价格数组相邻位置做差形成新的数组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]是最小价格,且他们满足前后顺序关系。
方法二:动态规划。
dp[i]表示从第0个元素到第i个元素最大的收益,miniprice是前i-1个元素中最小的股票价格,那么状态转移方程:
最终我们求出max{dp[0], dp[1], …,dp[len-1]}就行了
代码
方法一
class Solution {
public int maxProfit(int[] prices) {
int len = prices.length;
int k = 0;
int result = 0;
for(int i=1; i<len; i++){
if(k<=0){
k = prices[i]-prices[i-1];
}else{
k += prices[i]-prices[i-1];
}
result = Math.max(k, result);
}
return result;
}
}
方法二
class Solution {
public int maxProfit(int[] prices) {
int len = prices.length;
if(len==0 || len==1) return 0;
int[] dp = new int[len];
dp[0] = 0;
int miniprice = prices[0];
int result = 0;
for(int i=1; i<len; i++){
miniprice = Math.min(miniprice, prices[i-1]);
dp[i] = Math.max(dp[i-1], prices[i]-miniprice);
result = Math.max(result, dp[i]);
}
return result;
}
}