LeetCode——买卖股票的最佳时机

摘要:
今天最赚钱的是两种选择中的一种。最后一点是定义基本情况,这是最简单的情况。如果您最多只能完成一笔交易,请设计一个算法以实现利润最大化。publicintmaxProfit{ifsum=0;intsum=0;int min=prices[0];对于{ifsum=Math.max;elseifmin=prices[i];}returnsum;}以统一的方式执行:publicintmaxProfit{ifreturn0;intn=prices.length;int[][]dp=newint[n][2];dp[0][0]=0;//=max=0dp[0][1]=-prices[0];//=max for{dp[i][0]=Math.max;dp[i][1]=数学.max;}returndp[n-1][0];}Q: 假设您有一个数组,其中第i个元素表示第i天股票的价格。您可以完成任意数量的交易。但是,不能同时有多个事务。A: (自己做)所有上升斜率的最高点减去最低点publicstaticintmaxMaxProfit{ifretrn0;intmin=prices[0];intsum=0;for{ifmin=price[i];if{sum+=;min=prices[i];}returnsum;}事实上,它可以相当于无数的交易。

股票买卖分析:(引用自《labuladong的算法》)
LeetCode——买卖股票的最佳时机第1张
LeetCode——买卖股票的最佳时机第2张
这个解释应该很清楚了,如果 buy,就要从利润中减去 prices[i],如果 sell,就要给利润增加 prices[i]。今天的最⼤利润就是这两种可能选择中较⼤的那个。⽽且注意 k 的限制,我们在选择 buy 的时候,把 k 减⼩了 1,很好理解吧,当然你也可以在 sell 的时候减 1,⼀样的。
还差最后⼀点点,就是定义 base case,即最简单的情况。
LeetCode——买卖股票的最佳时机第3张

Q:假设你有一个数组,其中第i个元素是某只股票在第i天的价格。
如果你最多只能完成一笔交易(即买一股和卖一股股票),设计一个算法来求最大利润。
A:(自己做的)当前值比最小值小,代替最小值;当前值比最小值大,计算差值,和之前的差值做判断。

    public int maxProfit(int[] prices) {
        if (prices.length == 0)
            return 0;
        int sum = 0;
        int min = prices[0];
        for (int i = 1; i < prices.length; i++) {
            if (min < prices[i])
                sum = Math.max(sum, prices[i] - min);
            else if (min > prices[i])
                min = prices[i];
        }
        return sum;
    }

用统一方法做:

    public int maxProfit(int[] prices) {
        if (prices.length == 0)
            return 0;
        int n = prices.length;
        int[][] dp = new int[n][2];
        dp[0][0] = 0;//= max(0, -infinity + prices[i]) = 0
        dp[0][1] = -prices[0];//=max(-infinity, 0 - prices[i])
        for (int i = 1; i < n; 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], -prices[i]);
        }
        return dp[n - 1][0];
    }

Q:假设你有一个数组,其中第i个元素表示某只股票在第i天的价格。
设计一个算法来寻找最大的利润。你可以完成任意数量的交易(例如,多次购买和出售股票的一股)。但是,你不能同时进行多个交易(即,你必须在再次购买之前卖出之前买的股票)。
A:(自己做)所有的涨坡的最高点减最低点

    public static int maxProfit(int[] prices) {
        if (prices.length <= 1)
            return 0;
        int min = prices[0];
        int sum = 0;
        for (int i = 1; i < prices.length; i++) {
            if (prices[i] < min)
                min = prices[i];
            if (prices[i] > min && (i == prices.length - 1 || prices[i] >= prices[i + 1])) {
                sum += (prices[i] - min);
                min = prices[i];
            }
        }
        return sum;
    }

实际上可以相当于进行无数次买卖。

    public int maxProfit_inf(int[] prices) {
        int n = prices.length;
        int[][] dp = new int[n][2];
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        for (int i = 1; i < n; 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]);
        }
        return dp[n - 1][0];
    }

Q:假设你有一个数组,其中第i个元素是某只股票在第i天的价格。
设计一个算法来求最大的利润。你最多可以进行两次交易。
注意:
你不能同时进行多个交易(即,你必须在再次购买之前出售之前买的股票)。
A:(自己做)结合一下前两个代码,在每个峰值计算一次前后两个子数组的最大利润,相加比较。

    public static int maxProfit(int[] prices) {
        if (prices.length <= 1)
            return 0;
        int min = prices[0];
        int sum = 0;
        for (int i = 1; i < prices.length; i++) {
            if (prices[i] < min)
                min = prices[i];
            //找到峰值的时候
            if (prices[i] > min && (i == prices.length - 1 || prices[i] >= prices[i + 1])) {
                int left = max(Arrays.copyOfRange(prices, 0, i + 1));
                int right = 0;
                if (i != prices.length - 1) {
                    right = max(Arrays.copyOfRange(prices, i + 1, prices.length));
                }
                sum = Math.max(sum, (left + right));
                min = prices[i];
            }
        }
        return sum;
    }

    public static int max(int[] prices) {
        if (prices.length == 0)
            return 0;
        int sum = 0;
        int min = prices[0];
        for (int i = 1; i < prices.length; i++) {
            if (min < prices[i])
                sum = Math.max(sum, prices[i] - min);
            else if (min > prices[i])
                min = prices[i];
        }
        return sum;
    }

或者下面k次的方法把k改为2.

Q:假设你有一个数组,其中第i个元素是某只股票在第i天的价格。
设计一个算法来求最大的利润。你最多可以进行k次交易。
注意:
你不能同时进行多个交易(即,你必须在再次购买之前出售之前买的股票)。
A:⼀次交易由买⼊和卖出构成,⾄少需要两天。所以说有效的限制 k 应该不超过 n/2,如果超过,就没有约束作⽤了,相当于 k = +infinity

    public int maxProfit(int k, int[] prices) {
        if (k < 1 || prices.length == 0)
            return 0;
        int n = prices.length;
        if (k > n / 2) {//相当于k = +infinity
            return maxProfit_inf(prices);
        }
        int[][][] dp = new int[n][k + 1][2];
        for (int i = 0; i < n; i++) {
            for (int j = k; j >= 1; j--) {
                if (i == 0) {
                    dp[i][j][0] = 0;
                    dp[i][j][1] = -prices[0];
                } else {
                    dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]);
                    dp[i][j][1] = Math.max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - prices[i]);
                }
            }
        }
        return dp[n - 1][k][0];
    }

    private int maxProfit_inf(int[] prices) {
        int n = prices.length;
        int[][] dp = new int[n][2];
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        for (int i = 1; i < n; 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]);
        }
        return dp[n - 1][0];
    }

Q:给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。​
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
示例:
输入: [1,2,3,0,2]
输出: 3
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]
A:第 i 天选择 buy 的时候,要从 i-2 的状态转移,⽽不是 i-1 。

    public int maxProfit_inf(int[] prices) {
        if(prices.length == 0)
            return 0;
        int n = prices.length;
        int[][] dp = new int[n][2];
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        for (int i = 1; i < n; i++) {
            if(i==1){
                dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
                dp[i][1] = Math.max(dp[i - 1][1], - prices[i]);
                continue;
            }
            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 - 2][0] - prices[i]);//选择 buy 的时候,要从 i-2 的状态转移
        }
        return dp[n - 1][0];
    }

Q:给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 ;非负整数 fee 代表了交易股票的手续费用。你可以无限次地完成交易,但是你每次交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。返回获得利润的最大值。

示例 1:
输入: prices = [1, 3, 2, 8, 4, 9], fee = 2
输出: 8
解释: 能够达到的最大利润:
在此处买入 prices[0] = 1
在此处卖出 prices[3] = 8
在此处买入 prices[4] = 4
在此处卖出 prices[5] = 9
总利润: ((8 - 1) - 2) + ((9 - 4) - 2) = 8.

注意:
0 < prices.length <= 50000.
0 < prices[i] < 50000.
0 <= fee < 50000.

A:每次交易要⽀付⼿续费,只要把⼿续费从利润中减去即可。

    public int maxProfit_inf(int[] prices, int fee) {
        if(prices.length == 0)
            return 0;
        int n = prices.length;
        int[][] dp = new int[n][2];
        dp[0][0] = 0;
        dp[0][1] = -prices[0] - fee;
        for (int i = 1; i < n; 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] - fee);//在第⼀个式⼦⾥减也是⼀样的,相当于卖出股票的价格减⼩了。
        }
        return dp[n - 1][0];
    }

免责声明:文章转载自《LeetCode——买卖股票的最佳时机》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇使用python操作mysql数据库IIS连接数修改下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

ETF:pcf文件制作

pcf文件依赖数据: ETF基本信息() 指数权重文件(次日权重文件,中证指数公司) 现金替代标志文件(根据中证指数的停复牌文件) 净值文件(基金公司估值系统计算) 成分股数量计算公式: 1、估值系统计算申赎单位净值 2、净值乘以单只股票的权重计算单只股票金额,除以收盘价计算数量 3、数量取整,得到单只股票的数量 4、计算剩余剩余金额 5、将零股部分按照规...

量化学习 | 配对交易 backtrader实现

量化学习 | 配对交易 backtrader实现 配对交易,其基本原理就是找出两只走势相关的股票。这两只股票的价格差距从长期来看在一个固定的水平内波动,如果价差暂时性的超过或低于这个水平,就买多价格偏低的股票,卖空价格偏高的股票。等到价差恢复正常水平时,进行平仓操作,赚取这一过程中价差变化所产生的利润。 其实就是找到两个关联性高的股票A和B,做出调仓策略,...

金融量化分析-python量化分析系列之---使用python获取股票历史数据和实时分笔数据

财经数据接口包tushare的使用(一) Tushare是一款开源免费的金融数据接口包,可以用于获取股票的历史数据、年度季度报表数据、实时分笔数据、历史分笔数据,本文对tushare的用法,已经存在的一些问题做一些介绍。 一:安装tushare 为避免由于依赖包缺失导致安装失败,请先安装anaconda,百度网盘地址: 链接:http://pan.baid...

Python股票历史数据的获取

获取股票数据的接口很多,免费的接口有新浪、网易、雅虎的API接口,收费的就是证券公司及相应的公司提供的接口。收费试用的接口一般提供的数据只是最近一年或三年的,限制比较多,除非money足够多。所以本文主要讨论的是免费数据的获取及处理。 国内提供股票数据的接口如sinajs,money.163.com,yahoo,它们提供的API接口不同,每家提供的数据大同...

1.股票交易委托:买入、卖出操作

      股票委托交易,是指投资者在交易时间内,按交易所规则。进行股票买卖。 这里仅说A股:      什么是A股?        是指在我国境内发行,以人民币认购和交易的普通股股票。      交易所:       我国境内的证券交易所分为:上海证券交易所(沪市)、深圳证券交易所(深市);   沪市A股股票代码以6开头;深圳A股股票代码以0开头,创业板...

新浪股票接口AndroidSDK

昨天想到一个点子,需要访问股票行情。于是在网上搜了一下免费的股市行情的接口。发现新浪股票的数据接口比较稳定,于是就用它了。 网上对于新浪股票的数据接口介绍比较详细,并且实现也很简单,所以花了一下午就基本完成了。想到大家开发Android应用可能也会需要访问股市行情,特此将资料整理在此,并附上Javadoc文档和一个小Demo,以便后来人开发更为便捷。   ...