LC 121. 买卖股票的最佳时机
LC 121. 题目简述
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
思路分析
注意到题目中的股票买入只发生了一次,等价于在一个数组arr[0,n]之间对于,下标为 idx 的股票而言,[idx, n]中的最大值就是抛售的时刻t。
同时限定条件,也就是arr[t] - arr[idx] >=0 。
基本想法:
对于下标为0的股票,找到当前最大的抛售时间n, 则得到一个price,
同时对于[0,n]之间的股票也都在n处售卖,降低开销。
A trick.
if(prices[max] <= prices[idx]) max = idx; // 这里使得max尽可能得往后推移,在有重复值的时候减小开销
代码分享
public int maxProfit(int[] prices) {
int[] tmp = new int[prices.length];
for (int i = 0; i < prices.length; i++) {
tmp[i] = getMax(prices,i);
for (int j = i; j <= tmp[i]; j++) {
tmp[j] = tmp[i];
}
i = tmp[i];
}
int max = 0;
int profit = 0;
for (int i = 0; i < prices.length; i++) {
profit = prices[tmp[i]] - prices[i];
if(max < profit) max = profit;
}
return max;
}
public static int getMax(int[] prices,int idx){
// not comparing with itself
int max = idx;
while (idx < prices.length)
{
if(prices[max] <= prices[idx]) max = idx;
idx+=1;
}
if(max == idx) return idx;
else return max;
}
/*
执行用时:
348 ms
, 在所有 Java 提交中击败了
6.16%
的用户
内存消耗:
52.5 MB
, 在所有 Java 提交中击败了
86.27%
的用户
通过测试用例:
211 / 211
*/
后续改进可以使用in-place,无需创建新的数组,一次遍历得到max,maybe 可以提高 pass