• Day 49 | 121. 买卖股票的最佳时机 & 122. 买卖股票的最佳时机 II


    121. 买卖股票的最佳时机

     本题实际上就是求最低的价格买入,最高的价格卖出。卖出在买入之前。

    ①确定dp数组以及下标含义 

            dp[i][0]:第i天,持有股票的最大现金 

            dp[i][1]:第i天,不持有股票的最大现金

    ②确定递推公式

    每遍历一个金额,dp[i][0]有两个选择:

    1.买入股票 dp[i][0]=-price[i]

    2.保持原状 dp[i][0]=dp[i-1][0]

            因为买入-price[i]是负数,数字越小绝对值越大,因此取大值可以满足以更少的金额买入。

            两个都是负数,每次取两个的大值即可。

                                                    dp[i][0]=Math.max(dp[i-1][0],-prices[i])

    每遍历一个金额,dp[i][1]有两个选择:

    1.卖出股票 dp[i][1]=dp[i-1][0]+price[i]    //前一天持有的最大金额-今天的金额数,因为dp[i-1][0]是       负数,因此相加即可。

    2.保持原状 dp[i][1]=dp[i-1][1]   //不卖出,和上一天保持相同

       每次取两个的大值即可。

                                           dp[i][1]=Math.max(prices[i]+dp[i-1][0],dp[i-1][1])

            

    ③dp数组如何初始化

            dp[0][0]:第一天买入,初始值为-price[0]

            dp[0][1]:第一天不能卖出,初始值为0

    ④确定遍历顺序

               dp[i]由前面i-1决定,因此从前向后遍历

    ⑤举例推导dp数组

    1. public int maxProfit(int[] prices) {
    2. int[][] dp=new int[prices.length][2];
    3. dp[0][0]=-prices[0]; //dp[i][0]:第i天持有股票的最大现金
    4. dp[0][1]=0; //dp[i][1]:第i天卖出股票的最大现金
    5. for(int i=1;i
    6. dp[i][0]=Math.max(dp[i-1][0],-prices[i]);
    7. dp[i][1]=Math.max(prices[i]+dp[i-1][0],dp[i-1][1]);
    8. }
    9. return dp[prices.length-1][1];
    10. }

     

     122. 买卖股票的最佳时机 II

            看第一题我觉得还可以能接受,第二题公式勉强可以看懂,但是不知道为什么是这样,怎样想到这样,然后自己推导数组的时候也是完全一头雾水。。真的好难过呜呜呜

    本题与上题的区别在于可以多次买入卖出。

    dp数组定义与上题相同,区别在于递推公式买入股票。

    因为可以多次买入股票,因此当选择买入股票时。

            dp[i][0]:第i天,持有股票的最大现金 

            dp[i][1]:第i天,不持有股票的最大现金

    dp[i][0]应为前一天不持有股票的钱数-今天买入股票花费钱数,即dp[i][0]=dp[i-1][1]-price[i]

    1.买入股票 dp[i][0]=dp[i-1][1]-price[i]

    2.保持原状 dp[i][0]=dp[i-1][0]

    因此

                                    dp[i][0]=Math.max(dp[i - 1][0], dp[i - 1][1] - prices[i]);

    dp[i][1]与上题相同,卖出时为前一天持有金额+今天的金额

                                    dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i]);

    1. public int maxProfit(int[] prices) {
    2. int n = prices.length;
    3. int[][] dp = new int[n][2]; // 创建二维数组存储状态
    4. dp[0][1] = 0; // 初始状态
    5. dp[0][0] = -prices[0];
    6. for (int i = 1; i < n; ++i) {
    7. dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] - prices[i]); // 第 i 天,没有股票
    8. dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i]); // 第 i 天,持有股票
    9. }
    10. return dp[n - 1][1];
    11. }

     

  • 相关阅读:
    G1 GC核心原理、执行流程
    UE5 敌人血条
    从Spring为什么要用IoC的支点,我撬动了整个Spring的源码脉络
    [深度学习] 搭建行人重识别系统心得
    ThermalLabel SDK for .NET 11.0.22 Crack
    40个高质量ssm+vue毕设项目分享【源码+论文】(二)
    微服务主流框架概览
    论文阅读 (75):Video Anomaly Detection with Spatio-temporal Dissociation (2022)
    ABP 6.0.0-rc.1的新特性
    Web漏洞之文件包含漏洞
  • 原文地址:https://blog.csdn.net/m0_56579820/article/details/127744897