IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 力扣算法学习day34-3 -> 正文阅读

[数据结构与算法]力扣算法学习day34-3

力扣算法学习day34-3

123-买卖股票的最佳时机 III

题目

image-20220225001345004

image-20220225001652482

代码实现

class Solution {
    public int maxProfit(int[] prices) {
        // dp 速度:3ms
        // dp数组有5种状态
        // dp[i][0]:第i天   第一次持有      的最大利润
        // dp[i][1]:第i天   第一次未持有    的最大利润
        // dp[i][2]:第i天   第二次持有      的最大利润
        // dp[i][3]:第i天   第二次未持有    的最大利润
        // 分析:(下面利润也可以理解为现金,理解利润就是想成一定要是这个状态时的最大值,现金就是剩得最多)
        // 1. dp[i][0]:
        // 在第i天,第一次持有时(状态,故可以是前面买的)的最大利润,在i之前买入 或 这一天
        // 买入 这两种情况取最大值,即为第一次持有时的最大利润。
        // 迭代公式:dp[i][0] = Math.max(dp[i-1][0],-prices[i])
        // 2. dp[i][1]:
        // 第一次未持有时的最大利润,即在当前这天卖 或 之前就卖 中取最大值。
        // 迭代公式:dp[i][1] = Math.max(dp[i-1][1],prices[i] + dp[i-1][0])
        // 3. dp[i][2]:
        // 第二次持有时的最大利润,依赖于第一次卖出的情况,为第一次的利润减去当前(即当前为第
        // 二次买入) 或 之前买入第二次 中取最大值。
        // 迭代公式:dp[i][2] = Math.max(dp[i-1][2],dp[i-1][1] - prices[i])
        // 4. dp[i][3]:
        // 第二次未持有的最大值,和第一次卖出同理。
        // 迭代公式:dp[i][3] = Math.max(dp[i-1][3],dp[i-1][2] + prices[i])

        int[][] dp = new int[prices.length][4];

        // 初始化,这里主要需要注意dp[0][2]的初始化,因为dp[i][3]的迭代公式为dp[i-1][2] + prices[i]
        // ,所以在长度小于4的情况dp[i][3]实际上是没有意义的,但是迭代公式依然会计算,如果dp[0][2]初始化
        // 为0,像4,3这种数据会出现dp[1][3] = 3这种错误情况,所以需要将其初始化比-prices[i]相等或更小。
        // 这种初始化实际上是保证第一次卖出没有利润前,第二次卖出不会出现比第一次卖出更高的情况,而如果有
        // 利润,但是只需要卖一次的话,那么向示例2这种情况,第二次卖出会利润更小,因为第二次卖出必须要先卖
        // 出,然后再在第二天买入,那么第二次卖出比第一次卖出高的情况一定是出现在第一次卖出有利润 且 分两
        // 次卖出会高于一次卖出的情况。
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        dp[0][2] = Integer.MIN_VALUE;// 也可以是-price[0];
        dp[0][3] = 0;

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

        return Math.max(dp[prices.length-1][1],dp[prices.length-1][3]);
    }


    // 力扣官方的空间优化版本,代码取自代码随想录java模板,实际上时间上还是有提升。 速度:3ms
    // public int maxProfit(int[] prices) {
    //     int[] dp = new int[4]; 
    //     // 存储两次交易的状态就行了
    //     // dp[0]代表第一次交易的买入
    //     dp[0] = -prices[0];
    //     // dp[1]代表第一次交易的卖出
    //     dp[1] = 0;
    //     // dp[2]代表第二次交易的买入
    //     dp[2] = -prices[0];
    //     // dp[3]代表第二次交易的卖出
    //     dp[3] = 0;
    //     for(int i = 1; i <= prices.length; i++){
    //         // 要么保持不变,要么没有就买,有了就卖
    //         dp[0] = Math.max(dp[0], -prices[i-1]);
    //         dp[1] = Math.max(dp[1], dp[0]+prices[i-1]);
    //         // 这已经是第二次交易了,所以得加上前一次交易卖出去的收获
    //         dp[2] = Math.max(dp[2], dp[1]-prices[i-1]);
    //         dp[3] = Math.max(dp[3], dp[2]+ prices[i-1]);
    //     }
    //     return dp[3];
    // }
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-02-26 11:55:08  更:2022-02-26 11:59:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 16:45:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码