描述
假设你有一个数组prices,长度为n,其中prices[i]是股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益
- 你可以买入一次股票和卖出一次股票,并非每天都可以买入或卖出一次,总共只能买入和卖出一次,且买入必须在卖出的前面的某一天
- 如果不能获取到任何利润,请返回0
- 假设买入卖出均无手续费
示例:
- 输入:[8,9,2,5,4,7,1]
- 输出:5,买入2,卖出7
思路1:暴力破解,两两组合
时间复杂度O(n^n),超时
public class Solution {
public int maxProfit (int[] prices) {
int ret = 0;
for(int i = 0; i < prices.length - 1; i++) {
//卖出在买入之后
for(int j = i + 1; j < prices.length; j++) {
ret = Math.max(ret, prices[j] - prices[i]);
}
}
return ret;
}
}
思路2:双指针一次遍历
- i表示买入日期,j表示卖出日期,ret记录最大收益
prices[j] > prices[i]
时,表示上涨,否则表示下跌- 上涨时不能买入,i不变,j往后移
- 下跌时如果比买入价格低,更新买入价格。
- j继续往后移,查找是否还有上涨期
public class Solution {
public int maxProfit (int[] prices) {
int i = 0;
int j = 1;
int ret = 0;
while(j < prices.length) {
if(prices[j] <= prices[i]) {
i = j;
} else if(prices[j] > prices[i]) {
ret = Math.max(ret, prices[j] - prices[i]);
}
j++;
}
return ret;
}
}
思路3:记录最小值一次遍历
记录最小买入价格和最大收益。[5,99,2,5,4,7,1]
类似思路2,思路2是通过i记录最低买入价格日期
public class Solution {
public int maxProfit (int[] prices) {
int min = Integer.MAX_VALUE;
int ret = 0;
for(int price : prices) {
ret = Math.max(ret, price - min);
min = Math.min(price, min);
}
return ret;
}
}