持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
一、题目
LeetCode 买卖股票的最佳时机 II
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。
在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
示例 1:
输入:prices = [7,1,5,3,6,4]
输出:7
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。
总利润为 4 + 3 = 7 。
示例 2:
输入:prices = [1,2,3,4,5]
输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
总利润为 4 。
示例 3:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0 。
提示:
1 <= prices.length <= 3 * 104
0 <= prices[i] <= 104
二、题解
方法一
简单来说如果如果要获取利润,那就得低价买入高价卖出,因为给定的数组prices是固定的,那么我们可以找出能盈利的时间段,也就是数组的下标,然后统计出所有的盈利即可。同时如果需要盈利,最少需要当天买入,明天卖出;当天买入,当天卖出是不可能盈利的,那么我们就可以对所有的盈利进行统计了,如果发现昨天的股价比今天低,那么我们就需要在昨天买入,然后今天卖出,依次类推,最后统计返回总盈利即可。
方法二
最多只能持有一张股票,即如果当前持有股票没有卖出的情况下不能继续买入新股票,那么我们手里就只能是持有一张股票、或者不持有股票两种情况了。对此我们可以定义两个变量,来记录某天中持有股票的最大收益,以及不持有股票的最大收益,我们就从第一天开始往后计算收益。对于不持有股票的状态,其收益就是昨天不持有股票的收益或者是昨天持有的股票在今天卖出的收益。对于持有股票的状态,其收益就是昨天持有股票下的收益或者昨天没有股票但是今天买入了一个股票的收益。所以我们只有依次遍历数组,统计每一天下去持有的最大收益,最终不持有股票的收益是大于持有股票的收益的,最后返回不持有股票的状态下的收益即可。
三、代码
方法一 Java代码
class Solution {
public int maxProfit(int[] arr) {
int profit = 0;
for (int i = 1; i < arr.length; i++) {
if (arr[i] > arr[i - 1]) {
profit += (arr[i] - arr[i - 1]);
}
}
return profit;
}
}
时间复杂度:O(n),需要遍历一次数组元素。
空间复杂度:O(1),需要常数空间。
方法二
class Solution {
public int maxProfit(int[] prices) {
int hold = 0;
int notHold = -prices[0];
for (int i = 1; i < prices.length; ++i) {
int hold_ = hold;
hold = Math.max(hold, notHold + prices[i]);
notHold = Math.max(notHold, hold_ - prices[i]);
}
return hold;
}
}
时间复杂度:O(n),需要遍历一次数组元素。
空间复杂度:O(1),需要常数空间。