122. 买卖股票的最佳时机 II
题目
原题链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/
给定一个数组,它的第i个元素是一支给定股票第i天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例1:
输入: [7,1,5,3,6,4]
输出: 7
解释: 在第2天(股票价格=1)的时候买入,在第3天(股票价格=5)的时候卖出, 这笔交易所能获得利润=5-1=4。随后,在第4天(股票价格=3)的时候买入,在第5天(股票价格=6)的时候卖出, 这笔交易所能获得利润=6-3=3。
示例2:
输入: [1,2,3,4,5]
输出: 4
解释: 在第1天(股票价格=1)的时候买入,在第5天(股票价格=5)的时候卖出, 这笔交易所能获得利润=5-1=4。注意你不能在第1天和第2天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
示例3:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下,没有交易完成,所以最大利润为0。
解题思路
股票买卖情况:
-
单独交易日:设今天价格\(p_1\)、明天价格\(p_2\),则今天买入、明天卖出可赚取金额\(p_2 - p_1\)(负值代表亏损)。
-
连续上涨交易日(示例2):设此上涨交易日股票价格分别为\(p_1, p_2, ... , p_n\),则第一天买,最后一天卖收益最大,即\(p_n - p_1\);等价于“每天”都买卖,即\(p_n - p_1=(p_2 - p_1)+(p_3 - p_2)+...+(p_n - p_{n-1})\)。
- 虽然这样交易不符合题目要求,例如示例2:\([1,2,3,4,5]\),实际的交易过程并不是进行\(4\)次买入和\(4\)次卖出,而是在第\(1\)天买入,第\(5\)天卖出。
-
连续下降交易日(示例3):则不买卖收益最大,即不会亏钱。
对于今天的股价 - 昨天的股价
,得到的结果有3种可能:正数、0、负数。所以贪心算法的决策是:只加正数。即,将单独交易日
和连续上涨交易日
的情况合二为一(看prices[i] - prices[i - 1]
),如果prices[i] - prices[i - 1] > 0
,则添加至总利润
中。
代码实现
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 122. 买卖股票的最佳时机 II(多次交易)
*/
public class No122_BuyAndSellStock_II {
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 maxProfit = 0;
for (int i = 1; i < prices.length; i++) {
if (prices[i] - prices[i - 1] > 0) {
maxProfit += prices[i] - prices[i - 1];
}
}
return maxProfit;
}
}
复杂度分析
时间复杂度:\(O(n)\),其中\(n\)为数组的长度。我们只需要遍历一次数组即可。
空间复杂度:\(O(1)\)。只需要常数空间存放若干变量。