面试经典150题 买卖股票的最佳时机 II

文章讲述了如何使用动态规划和贪心策略解决股票交易中的问题,通过比较两种方法,分析了从数组中获取最大利润的算法,包括时间复杂度和空间复杂度。重点介绍了如何通过一次遍历找到不相交的区间以最大化收益。
摘要由CSDN通过智能技术生成

题目来源

力扣每日一题;题序:122

我的题解

方法一 动态规划

买卖股票的最佳时机 的区别在于:可以多次买入、卖出。

时间复杂度:O(n)
空间复杂度:O(n)

public int maxProfit(int[] prices) {
    int n=prices.length;
    int[][] dp=new int[n][2];//0买 1卖
    for(int i=0;i<n;i++){
        if(i==0){
            dp[i][0]=-prices[0];
            dp[i][1]=0;
            continue;
        }
        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]);
    }
    return dp[n-1][1];
}
//空间优化版本
public int maxProfit(int[] prices) {
    int n=prices.length;
    int dp_0=-prices[0];//买
    int dp_1=0;//卖
    for(int i=1;i<n;i++){
        int t=dp_0;
        dp_0=Math.max(dp_0,dp_1-prices[i]);
        dp_1=Math.max(dp_1,t+prices[i]);
    }
    return dp_1;
}
方法二 贪心+一次遍历

由于股票的购买没有限制,因此整个问题等价于寻找 x 个不相交的区间 ( l i , r i ] (l_i,r_i] (li,ri]使得如下的等式最大化 ∑ i = 1 x a [ r i ] − a [ l i ] i = 1 \sum_{i=1}^{x} a[r_i]-a[l_i] i=1 i=1xa[ri]a[li]i=1,其中 l i l_i li 表示在第 l i l_i li天买入, r i r_i ri表示在第 r i r_i ri天卖出。同时注意到对于 ( l i , r i ] (l_i,r_i] (li,ri]这一个区间贡献的价值 a [ r i ] − a [ l i ] a[r_i]-a[l_i] a[ri]a[li],其实等价于 ( l i , l i + 1 ] , ( l i + 1 , l i + 2 ] , … , ( r i − 1 , r i ] (l_i,l_i+1],(l_i+1,l_i+2],\ldots,(r_i-1,r_i] (li,li+1],(li+1,li+2],,(ri1,ri]这若干个区间长度为 1 的区间的价值和,即
a [ r i ] − a [ l i ] = ( a [ r i ] − a [ r i − 1 ] ) + ( a [ r i − 1 ] − a [ r i − 2 ] ) + … + ( a [ l i + 1 ] − a [ l i ] ) a[r_i]-a[l_i]=(a[r_i]-a[r_i-1])+(a[r_i-1]-a[r_i-2])+\ldots+(a[l_i+1]-a[l_i]) a[ri]a[li]=(a[ri]a[ri1])+(a[ri1]a[ri2])++(a[li+1]a[li])
因此问题可以简化为找 x 个长度为 1 的区间 ( l i , l i + 1 ] (l_i,l_i+1] (li,li+1]使得 ∑ i = 1 x a [ l i + 1 ] − a [ l i ] \sum_{i=1}^{x} a[l_i+1]-a[l_i] i=1xa[li+1]a[li]价值最大化。
贪心的角度考虑每次选择贡献大于 0 的区间即能使得答案最大化,因此最后答案为 ans = ∑ i = 1 n − 1 max ⁡ { 0 , a [ i ] − a [ i − 1 ] } \textit{ans}=\sum_{i=1}^{n-1}\max\{0,a[i]-a[i-1]\} ans=i=1n1max{0,a[i]a[i1]},其中 n 为数组的长度。
贪心算法只能用于计算最大利润,计算的过程并不是实际的交易过程。

时间复杂度:O(n)
空间复杂度:O(1)

public int maxProfit(int[] prices) {
    int total=0;
    int len=prices.length;
    for(int i=1;i<len;i++){
        if(prices[i]>prices[i-1]){
            total+=prices[i]-prices[i-1];
        }
    }
    return total;
}

有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜菜的小彭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值