【Java】【LeetCode】买卖股票的问题

这篇文章仅用于记录自己学习。

股票问题全文只用DP
只用动态规划来做,其他的方法我自己没写。

建议大家先了解一下动态规划。

先从最简单的买卖股票开始吧(第121题)。
在这里插入图片描述
其实这题之前我自己用动态规划也不太会,想了好久,只能说算是明白一点点了吧。

在这个问题中
就是一点,第一,股票每天的利润怎么算。
我把股票利润分为两种。

在第i天的时候,我把股票买入,第K天,我把股票卖出。 那么 在0~i天和k-最后一天,我的手上没有股票, 在i-k天,手上有股票

我定义一个二维dp数组

int [][]dp = new int[len][2];

dp[ i ][ 0 ]表示第 i 天的时候我的手上没有股票,在那一天我可以获得的利润
同理
dp[ i ][ 1 ]表示第 i 天的时候我的手上持有股票,在那一天我可以获得的利润
那好,我先初始化这两个数组

dp[0][0]=0;//没有股票
dp[0][1]=-prices[0];//持有股票

初始化的值怎么算的?
因为第一天,要么你没买股票,那利润就是0 即:dp[ 0 ][ 0 ] = 0;
那买了股票,(第一天)利润就是 -prices[ 0 ]
我们把-price[0]看做一个整体,就是获得的利润,

我只需要求出每一天的dp数组的值,也就是每一天的利润,就可以拿到最大值

for (int i = 0; i < len; i++) {
     dp[i][0]=Math.max(dp[i-1][0],prices[i]+dp[i-1][1]);       
}

一个for循环
假设第i天我没持有股票第i天的利润就是dp[i][0],是不是有两种情况:1,前一天我也没有股票,今天也没有;2,前一天我有股票,但是我今天卖了:
1,·前一天我没有股票,那是不是和今天一样的情况?(就是相对于前一天来说,前一天没有持有股票,前一天也有这两种情况),那么代码是不是dp[i-1][0] (dp[ ][ ]后面只有0和1; 0表示没有股票,1表示有股票)
就是相当于递归了?
2,前一天我有股票,今天我卖了,那么利润是不是prices[i]+dp[i-1][1]
记住这里,非常重要:
这里怎么理解?
因为在整个问题中,股票只有一次买卖,那如果说,我前一天持有股票了,那么我到卖出那一天为止利润是不是一直都是负数?
比如说我第一天买,第3天卖,那么对于第一天,第二天来说,利润是不是一直都是负数,因为没有卖。
这样理解:
第一天花了3块买入,第二天的价格是5,第三天价格为7,
第二天我可以把股票卖出去(卖出去利润就是正的了),但是我没有卖,那么对于第三天来说,利润到目前为止是不是亏了3块?
就是 -3.
就是这样,所以对于第二种情况 :前一天我有股票,今天我卖了,利润就是:
在这里插入图片描述
好了,这种情况搞定了,剩下的就是第i天我还持有股票的情况了:
也是有两种情况
前一天我一直持有股票,那是不是和上面一样:
利润:dp[i-1][i]
前一天我没有股票,那么我今天买入
利润:-prices[i]
那么第i天我持有股票的利润:
dp[i][1]=Math.max(dp[i-1][1],-prices[i]);
总结一下两种情况:
//第 i 天 我没持有股票的利润:
dp[i][0]=Math.max(dp[i-1][0],prices[i]+dp[i-1][1]);
//第 i 天 我\持有股票的利润:
dp[i][1]=Math.max(dp[i-1][1],-prices[i]);
然后选择最大利润
max =Math.max(dp[i][0],dp[i][1])
可以了,返回max就行了
全部代码如下:

 public static int maxProfit(int[] prices) {
        int len =prices.length;
        int [][]dp = new int[len][2];
        int max= 0;
        dp[0][0]=0;//没有股票
        dp[0][1]=-prices[0];//有股票
        for (int i = 1; i < len; i++) {
            dp[i][0]=Math.max(dp[i-1][0],prices[i]+dp[i-1][1]);
            dp[i][1]=Math.max(dp[i-1][1],-prices[i]);
             max =Math.max(dp[i][0],dp[i][1])
        }
        return max;
        
    }

可AC
在这里插入图片描述

第122题 买卖股票的最佳时机 II

在这里插入图片描述

和上面题解一样,唯一不一样的是情况分析:
假设第i天我没持有股票第i天的利润就是dp[i][0],两种情况:1,前一天我也没有股票,今天也没有;2,前一天我有股票,但是我今天卖了:
前一天也没有股票,那么利润就是dp[i-1][0]
前一天有股票,今天卖了,那么利润就是,前一天持有股票的利润加上今天的利润
其实上面也是一样的,只不过前一天持有的利润是负数而已,而这题利润可能是正数,其实利润也是dp[i-1][1]+prices[i]

***************************************************************

假设第i天我持有股票,两种情况
前一天我持有股票,那么利润就是dp[i-1][1]
前一天我没有股票,今天买入股票,那么利润就是前一天的利润减去今天购买股票花的钱
怎么理解?
比如说价格; 7 1 3 5 6 4 5
对于第四天的5来说
我假如在第2天买了股票,利润为-1,
第三天我卖了,利润是不是2? 利润为2
那么对于第四天的5来说,5的前一天利润是不是3?那么今天的利润不就是前一天的利润减去今天购买股票花的钱嘛
所以前一天没有股票,今天买入股票,今天的利润就是:dp[i-1][0]-prices[i]
好,没差别了,剩下的就是一样的
我给你们看看差别的地方:
121:
在这里插入图片描述

122
在这里插入图片描述
代码差别:

//121
for (int i = 1; i < len; i++) {
            dp[i][0]=Math.max(dp[i-1][0],prices[i]+dp[i-1][1]);
            dp[i][1]=Math.max(dp[i-1][1],-prices[i]);
            max =Math.max(dp[i][0],dp[i][1]);
	}
//122
for (int i = 1; i < len; 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]);
            max =Math.max(dp[i][0],dp[i][1]);
     }

好了,这是第二个股票问题
全部代码如下:

public int maxProfit(int[] prices) {
        int len =prices.length;
        int [][]dp = new int[len][2];
        int max= 0;
        dp[0][0]=0;//没有股票
        dp[0][1]=-prices[0];//有股票
        for (int i = 1; i < len; 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]);
            max =Math.max(dp[i][0],dp[i][1]);
        }
        return max;
    }

AC图片如下:
在这里插入图片描述

股票问题接下来还会更新,可以收藏一下!

文章仅用于我学习记录所用,有些部分是从其他地方借鉴学习而来,如内容有所侵权,联系我删除,
如果还有其他想和我讨论的,欢迎大家联系我!!
一起打卡学习!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值