121. 买卖股票的最佳时机
题目
原题链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/
给定一个数组,它的第i个元素,是一支给定股票第i天的价格。
如果只能选择某一天买入这只股票,并选择在未来的某一个不同的日子卖出该股票。即,最多只允许完成一笔交易,设计一个算法来计算你所能获取的最大利润。
注意:你不能在买入股票前,卖出股票。
示例1:
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第2天(股票价格=1)的时候买入,在第5天(股票价格=6)的时候卖出,最大利润=6-1=5。
注意:利润不能是7-1=6,因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
示例2:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为0。
解题思路
需要找出给定数组中,两个数字之间的最大差值(即,最大利润)。此外,第二个数字(卖出价格)必须大于第一个数字(买入价格)。
形式上,对于每组\(i\)和\(j\)(其中\(j > i\)),需要找出\(\max(prices[j] - prices[i])\)。
代码实现思路:
遍历价格数组,找到
一个历史最低价格minPrice
,可以假设股票是在那天买的。那么,如果在第\(i\)天卖出股票,得到的利润prices[i] - minprice
大于先前得到的最大利润maxProfit
,则更新最大利润。当考虑完所有天数之时,就得到了答案。
即prices[i]
存在三种情况:
prices[i] < minPrice
:那么就找到了一个潜在的最佳买进时间
,更新minPrice
;prices[i] = minPrice
:不买不卖;prices[i] > minPrice
:此时卖出,可赚利润为prices[i] - minPrice
,如果大于maxProfit
,则更新最大利润。
代码实现
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 121. 买卖股票的最佳时机(只交易一次)
*/
public class No121_BuyAndSellStock {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] strings = reader.readLine().split(",");
int[] prices = new int[strings.length];
for (int i = 0; i < strings.length; i++) {
prices[i] = Integer.parseInt(strings[i]);
}
System.out.println(getMaxProfit(prices));
}
public static int getMaxProfit(int[] prices) {
int minPrice = Integer.MAX_VALUE;
int maxProfit = 0;
/**
* prices[i]存在三种情况:
* 1. prices[i] < minPrice:那么就找到了一个潜在的最佳买进时间
* 2. prices[i] = minPrice:不买不卖
* 3. prices[i] > minPrice:此时卖出,可赚利润为prices[i] - minPrice
*/
for (int i = 0; i < prices.length; i++) {
if (prices[i] < minPrice) {
minPrice = prices[i];
} else if (prices[i] - minPrice > maxProfit) {
maxProfit = prices[i] - minPrice;
}
}
return maxProfit;
}
}
复杂度分析
时间复杂度:\(O(n)\),只需要遍历一次。
空间复杂度:\(O(1)\),只使用了常数个变量。