题解 | #股票交易日#

股票交易日

https://www.nowcoder.com/practice/3e8c66829a7949d887334edaa5952c28

import java.util.*;

public class Stock {
    public int maxProfit(int[] prices, int n) {
        // return solution1(prices, n);
        // return solution2(prices, n);
        return solution3(prices, n);
    }

    /**
     * 动态规划: 状态机
     *
     * 两次交易同时开始
     *
     * dp[i][0]表示股票前i种价格第一次交易买入后所得收益
     * dp[i][1]表示股票前i种价格第一次交易卖出后所得收益
     * dp[i][2]表示股票前i种价格第二次交易买入后所得收益
     * dp[i][3]表示股票前i种价格第二次交易卖出后所得收益
     *
     * 四种状态:
     * 第一次交易买入: 要么是之前买的, 要么是今天买的
     * 第一次交易卖出: 要么是之前卖的, 要么是今天卖的
     * 第二次交易买入: 要么是之前买的, 要么是今天买的
     * 第二次交易卖出: 要么是之前卖的, 要么是今天卖的
     *
     * 分别对应关系式:
     * dp[i][0] = max(dp[i-1][0], -prices[i])
     * dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i])
     * dp[i][2] = max(dp[i-1][2], dp[i-1][1]-prices[i])
     * dp[i][3] = max(dp[i-1][3], dp[i-1][2]+prices[i])
     *
     * @param prices
     * @param n
     * @return
     */
    private int solution1(int[] prices, int n){
        int[][] dp = new int[n][4];

        // 一次买入
        dp[0][0] = -prices[0];
        // 一次卖出
        dp[0][1] = 0;
        // 二次买入
        dp[0][2] = -prices[0];
        // 二次卖出
        dp[0][3] = 0;
        for(int i=1; i<n; i++){
            dp[i][0] = Math.max(dp[i-1][0], -prices[i]);
            dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]+prices[i]);
            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 dp[n-1][3];
    }

    /**
     * 动态规划: 状态机
     *
     * 两次交易同时开始
     *
     * buy1 表示股票前i种价格第一次交易买入后所得收益
     * sell1 表示股票前i种价格第一次交易卖出后所得收益
     * buy2 表示股票前i种价格第二次交易买入后所得收益
     * sell2 表示股票前i种价格第二次交易卖出后所得收益
     *
     * 四种状态:
     * 第一次交易买入: 要么是之前买的, 要么是今天买的
     * 第一次交易卖出: 要么是之前卖的, 要么是今天卖的
     * 第二次交易买入: 要么是之前买的, 要么是今天买的
     * 第二次交易卖出: 要么是之前卖的, 要么是今天卖的
     *
     * 分别对应关系式:
     * buy1 = max(buy1, -prices[i])
     * sell1 = max(sell1, buy1+prices[i])
     * buy2 = max(buy2, sell1-prices[i])
     * sell2 = max(sell2, buy2+prices[i])
     *
     * @param prices
     * @param n
     * @return
     */
    private int solution2(int[] prices, int n){
        // 一次买入
        int buy1 = -prices[0];
        // 一次卖出
        int sell1 = 0;
        // 二次买入
        int buy2 = -prices[0];
        // 二次卖出
        int sell2 = 0;
        for(int i=1; i<n; i++){
            buy1 = Math.max(buy1, -prices[i]);
            sell1 = Math.max(sell1, buy1+prices[i]);
            buy2 = Math.max(buy2, sell1-prices[i]);
            sell2 = Math.max(sell2, buy2+prices[i]);
        }

        return sell2;
    }

    /**
     * 动态规划: 双向
     * @param prices
     * @param n
     * @return
     */
    private int solution3(int[] prices, int n){
        int[] left = new int[n];
        int[] right = new int[n];
        int leftMin = prices[0];
        int rightMax = prices[n-1];
        int sum = 0;
        
        // 左段一次交易最大收益
        for(int i=1; i<n; i++){
            leftMin = Math.min(prices[i], leftMin);
            left[i] = Math.max(prices[i]-leftMin, left[i-1]);
        }
        // 右段一次交易最大收益
        for(int i=n-2 ; i>=0; i--){
            rightMax = Math.max(prices[i], rightMax);
            right[i] = Math.max(rightMax-prices[i], right[i+1]);
        }
        // 两次交易最大收益
        for(int i=0 ; i<n; i++){
            sum = Math.max(sum, left[i]+right[i]);
        }

        return sum;
    }
}

全部评论

相关推荐

不愿透露姓名的神秘牛友
07-09 13:05
TMD找工作本来就烦,这东西什么素质啊😡
Beeee0927:hr是超雄了,不过也是有道理的
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-10 11:27
明天又是董事长面,啥时候是个头啊
积极向上的林同学:董事长亲自面试
点赞 评论 收藏
分享
06-20 17:42
东华大学 Java
凉风落木楚山秋:要是在2015,你这简历还可以月入十万,可惜现在是2025,已经跟不上版本了
我的简历长这样
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-08 12:05
俺不中了,BOSS遇到了一个hr,我觉得我咨询的问题都很正常吧,然后直接就被拒绝了???
恶龙战士:你问的太多了,要不就整理成一段话直接问他,一个一个问不太好
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务