买卖股票的最佳时机 II
今天的题目是力扣面试经典150题中的数组的中等难度题:买卖股票的最佳时机 II。
题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/description/?envType=study-plan-v2&envId=top-interview-150
问题描述
给定一个整数数组 prices,其中 prices[i] 表示某支股票第 i 天的价格。设计一个算法来找出你能获取的最大利润。你可以尽可能多地完成交易(多次买卖一支股票)。注意:你不能同时参与多笔交易(你必须在再次购买前卖出股票)。
- 示例
- 输入:
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 。
根据上面内容,我们可以发现,在这个问题中,关键是要理解可以进行多次买卖,并且每次买卖之间没有间隔限制。这意味着只要股票价格有上升的趋势,就可以立即买入并卖出以获取利润。
里面有点要注意的是,理论上讲我们需要买入一次卖出一次获取利润。但是实际操作的时候,由于有连续增长的情况,比如数组是[1,2,6]这种,我们正常应该是1买入,6卖出,利润5,但是在我们编写算法的时候,我们可以买卖两次,即1买入,2卖出,2再买入,6卖出。这样利润一样是5,但是相比直接1买入6卖出,我们需要编写的代码无疑简单很多。
也就是说我们可以直接两两比较,当后面的值大于前面的值,那么就可以在前面的值买入,后面的值卖出,这样就可以获得最大利润。
解题思路
- 定义变量利润值为0;
- 循环数组,这次我们从0开始循环,因为我们直接考虑两两比较相加得值,所以我们注意循环次数 = 数组长度-1,不能导致索引越界。
- 如果后面的值大,则计算利润。
- 返回利润值。
这种思路其实是贪心算法的思路,就是将每次可能的利润都加上,来获取最大的利润值。
实际算法代码
以下是使用上述思路的 Java 实现:
public class Solution {
public static void main(String[] args) {
Solution solution = new Solution();
int[] prices = {7, 1, 5, 3, 6, 4};
int maxProfit = solution.maxProfit(prices);
System.out.println("Maximum profit: " + maxProfit);
}
public int maxProfit(int[] prices) {
// 定义利润值
int profit = 0;
// 循环数组,计算每次可能获取的利润并相加
for (int i = 0; i < prices.length - 1; i++) {
if (prices[i + 1] > prices[i]) {
profit += prices[i + 1] - prices[i];
}
}
// 返回结果
return profit;
}
}
结果
启动程序,结果符合预期:
同样提交到力扣,依旧通过,并且效果还不错的样子。
总结
通常来说,贪心算是是这类型题目的优秀解法。理解好贪心算法和充分了解目标结构数组,是快速且优秀的完成之类题目解答的重要条件。
最后预告一下,数组的题目解答完以后,我单独讲数组中用到的解法再学习总结一下,包括双指针法,贪心算法等等。
加油!!!