买卖股票的最佳时机 II
作者:互联网
给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x2zsx1/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
下面参考了leetcode大神的题解,进行了解法的整理
方法1:最简单的方法:找到算法规律/最大化贪心
股票可能会买入也可能不买,股票的价格在一段时间内会上升也可能会下降,怎么知道在未来股票的最大价格?然后决定现在是不是应该买入或卖出?
先不想那么多,我们不是要预测未来而是面对一个给定的数组,因此我们始终能给出最优解:明天的价格只要上升,今天就买入,明天的价格只要下降今天就卖出
因此这就是一个上升区间累加的贪心问题,不要被股票给唬住,因为我们能知道明天是什么样总能给出最优解。ps:说了这么多,其实是因为作为一个小白,我的思路一开始就被唬住了。
/**
* 只要当天价格大于昨天,就可以作差累计收益
* @param prices
* @return
*/
public static int maxProfit(int[] prices) {
if (prices.length == 1) {
return 0;
}
int res = 0;
for (int i = 1; i < prices.length; i++) {
if (prices[i] > prices[i - 1]) {
res += (prices[i] - prices[i - 1]);
}
}
return res;
}
方法2:贪心
如果当天只能买入或卖出呢?那就要分区间考虑,找到区间的最小值和最大值进行作差,然后累加到结果
/**
* 计算区间,寻找区间的最小值和最大值,然后作差累加到结果
* 在区间内的循环比较时,index始终指向最值,即循环满足条件index++去指向最值
* 区间结束index++键入下一区间
*
* @param prices
* @return
*/
public static int maxProfit(int[] prices) {
int len = prices.length;
if (len == 1) {
return 0;
}
int index = 0;
int res = 0;
while (index < len) {
while (index < len - 1 && prices[index] > prices[index + 1]) {
index++; //以上两个条件都满足,说明index不是最后一位,且下一位的值比当前位更小,则index++指向下一位
}
int min = prices[index]; //循环结束或不进入循环都说明index指向最小位
while (index < len - 1 && prices[index] < prices[index + 1]) {
index++; //以上两个条件都满足,说明index不是最后一位,且下一位的值比当前位更大,则index++指向下一位
}
res += prices[index] - min;
index++;//上述过程找到了一个区间的最大最小值,此时index++进入下一区间
}
return res;
}
方法3:动态规划
在看leetcode题解时看到的动态规划解法。正好可以用这道简单题写写动态规划
如果当前的状态与上一次的状态有关就可以使用动态规划。
/**
* 动态规划
* 1.当前一天状态只收前一天状态影响
* 2.每天交易完由两个状态,持有股票,不持有股票
* 3.分析两种状态和前一天两种状态的关系
* 4.考虑初态
*/
public static int maxProfit(int[] prices) {
int n = prices.length;
if(n == 1){
return 0;
}
int res = 0;
int[][] dp = new int[n][2]; //n对应每天 每天具有两个状态 0为不持有股票 1为持有股票
//dp数组初态
dp[0][0] = 0;//第一天不买入
dp[0][1] = -prices[0];//第一天买入
for(int i = 1; i < n; i++){
//今天未持有股票只能是今天没有交易,或前一天就没有持有股票
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
//今天持有股票只能是今天买入,或前一天就持有
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
}
res = Math.max(dp[n - 1][0], dp[n - 1][1]);//最后一天结果取最大值;
return res;
}
方法4 动态规划优化
/**
* 动态规划的dp数组是为了记住更早时间的状态
* 如果当前状态至于前一天的状态有关,那么可以只有状态相同数量的变量存储就可以
* 也就是说更早的状态无用
*/
public static int maxProfit(int[] prices) {
int n = prices.length;
if(n == 1){
return 0;
}
int res = 0;
//dp数组初态
int noHold = 0;//第一天不买入
int hold = -prices[0];//第一天买入
for(int i = 1; i < n; i++){
//今天未持有股票只能是今天没有交易,或前一天就没有持有股票
int temp = noHold;
noHold = Math.max(noHold, hold + prices[i]);
//今天持有股票只能是今天买入,或前一天就持有
hold = Math.max(hold, temp - prices[i]);
}
res = Math.max(noHold, hold);//最后一天结果取最大值;
return res;
}
标签:index,买卖,int,res,II,++,最佳时机,prices,dp 来源: https://www.cnblogs.com/zjq-blog/p/15387821.html