• [LeetCode] 121. 买卖股票的最佳时机 ☆(动态规划)


    https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-29/

    描述

    给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

    如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

    注意你不能在买入股票前卖出股票。

    示例 1:

    输入: [7,1,5,3,6,4]
    输出: 5
    解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
    注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
    示例 2:

    输入: [7,6,4,3,1]
    输出: 0
    解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

    解析

    普通思路

    先找出最小值,再在最小值后面找到最大值即可。

    期间,最小值可能会变化,所以差值也会变化。

    动态规划

    参考连续子数组和。

    其解法:

    用一个一维数组 dp [ i ] 表示以下标 i 结尾的子数组的元素的最大的和,也就是这个子数组最后一个元素是下边为 i 的元素,并且这个子数组是所有以 i 结尾的子数组中,和最大的。

    这样的话就有两种情况,

    • 如果 dp [ i - 1 ] < 0,那么 dp [ i ] = nums [ i ]。
    • 如果 dp [ i - 1 ] >= 0,那么 dp [ i ] = dp [ i - 1 ] + nums [ i ]。
    public int maxSubArray(int[] nums) {
        int n = nums.length;
        int dp = nums[0];
        int max = nums[0]; 
        for (int i = 1; i < n; i++) {
            dp= Math.max(dp + nums[i],nums[i]);
            max = Math.max(max, dp);
        }
        return max;
    }
    View Code

    而对于这道题我们可以转换成上边的问题。

    对于数组 1 6 2 8,代表股票每天的价格。

    定义一下转换规则,当前天的价格减去前一天的价格,第一天由于没有前一天,规定为 0,用来代表不操作。

    数组就转换为 0 6-1 2-6 8-2,也就是 0 5 -4 6。现在的数组的含义就变成了股票相对于前一天的变化了。

    现在我们只需要找出连续的和最大是多少就可以了,也就是变成了 53 题。

    连续的和比如对应第 3 到 第 6 天加起来的和,那对应的买入卖出其实就是第 2 天买入,第 6 天卖出。

    换句话讲,买入卖出和连续的和形成了互相映射,所以问题转换成功。

    代码在上边的基础上改一下就可以了。下面。。

    代码

    普通思路

    public int maxProfit(int[] prices) {
            if (null == prices || prices.length < 2) {
                return 0;
            }
            int min = Integer.MAX_VALUE;
            int res = 0;
            for (int i = 0; i < prices.length; i++) {
                int value = prices[i];
                if (value < min) {
                    min = value;
                } else if (value - min > res) {
                    res = value - min;
                }
            }
            return res;
        }

    动态规划

    public static int maxProfit(int[] prices) {
            int dp = 0;
            int max = 0;
            for (int i = 1; i < prices.length; i++) {
                int cha = prices[i] - prices[i - 1];
                dp = Math.max(dp + cha, cha);
                max = Math.max(max, dp);
            }
            return max;
        }
  • 相关阅读:
    DATAGUARD物理standby角色切换(笔记二)
    深入了解start with .....connect by (一)
    oracle lob字段处理
    InstallShield12命令行模式编译工程的几点问题总结Emma友情赞助转帖
    Installshield实用小函数为字符串截掉头尾空格
    使用Java Service Wrapper将Java程序发布成Windows Service艾泽拉斯之海洋女神出品
    Kevin专栏自定义安装对话框的界面
    Kevin专栏如何制作试用版安装包
    【海洋女神原创】关于installshield“完美卸载”的改进方法
    Installshield的相对路径问题
  • 原文地址:https://www.cnblogs.com/fanguangdexiaoyuer/p/11599725.html
Copyright © 2020-2023  润新知