• 122 买卖股票的最佳时机||(状态机DP)(灵神笔记)


    题目

    链接
    给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。

    在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

    返回 你能获得的 最大 利润 。

    示例 1:

    输入:prices = [7,1,5,3,6,4]
    输出:7
    解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
    随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。
    总利润为 4 + 3 = 7 。
    示例 2:

    输入:prices = [1,2,3,4,5]
    输出:4
    解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
    总利润为 4 。
    示例 3:

    输入:prices = [7,6,4,3,1]
    输出:0
    解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0 。

    提示:

    1 <= prices.length <= 3 * 104
    0 <= prices[i] <= 104

    题解

    记忆化搜索

    class Solution {
        private int[] prices;
        private int[][] cache;
    
        public int maxProfit(int[] prices) {
            this.prices = prices;
            int n = prices.length;
            cache = new int[n][2];
            for (int i = 0; i < n; i++) {
                Arrays.fill(cache[i],-1);
            }
            //最后一天不选,以免浪费钱
            return dfs(n - 1, 0);
        }
    
        private int dfs (int i, int hold) {
            if (i < 0) {
                //dfs(-1,0)第0天没有股票 初始化为0
                //dfs(-1,1)第0天有股票 不合法
                return hold == 1 ? Integer.MIN_VALUE : 0;
            }
            if (cache[i][hold] != -1) {
                return cache[i][hold];
            }
            if (hold == 1) {
                //选择买股票
                return cache[i][hold] = Math.max(dfs(i - 1, 1), dfs(i - 1, 0) - prices[i]);
            }
            //不买股票
            return cache[i][hold] = Math.max(dfs(i - 1, 0), dfs(i - 1, 1) + prices[i]);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    递推

    class Solution {
        public int maxProfit(int[] prices) {
            int n = prices.length;
            //下标-1是越界的,因此需要+1
            int[][] f = new int[n + 1][2];
            f[0][1] = Integer.MIN_VALUE;
            for (int i = 0; i < n; i++) {
                f[i + 1][0] = Math.max(f[i][0], f[i][1] + prices[i]);
                f[i + 1][1] = Math.max(f[i][1], f[i][0] - prices[i]);
            }
            return f[n][0];
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    空间优化

    class Solution {
        public int maxProfit(int[] prices) {
            int f0 = 0, f1 = Integer.MIN_VALUE;
            for (int p : prices) {
                int newf0 = Math.max(f0, f1 + p);
                f1 = Math.max(f1, f0 - p);
                f0 = newf0;
            }
            return f0;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    Pytorch深度强化学习1-3:策略评估与贝尔曼期望方程详细推导
    Small RTOS51 学习笔记(8)信号量
    ADSP-21489的图形化编程详解(7:延时、增益、分频、反馈、响度)
    kubernetes apparmor 简介
    01 - Linux系统概要(再论计算机系统)
    windows系统当程序动态调用动态链接库dll时的搜寻路径及搜寻顺序
    C Primer Plus(6) 中文版 第11章 字符串和字符串函数 11.6 字符串示例:字符串排序
    Oracle笔记 之 空值null的处理
    Docker搭建RK3568开发环境
    【C语言】归并排序
  • 原文地址:https://blog.csdn.net/fffffall/article/details/133938931