zoukankan      html  css  js  c++  java
  • Leetcode 714. Best Time to Buy and Sell Stock with Transaction Fee

    题目

    链接:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/

    **Level: ** Medium

    Discription:
    Your are given an array of integers prices, for which the i-th element is the price of a given stock on day i; and a non-negative integer fee representing a transaction fee.

    You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction. You may not buy more than 1 share of a stock at a time (ie. you must sell the stock share before you buy again.)

    Return the maximum profit you can make.

    Example 1:

    Input: prices = [1, 3, 2, 8, 4, 9], fee = 2
    Output: 8
    Explanation: The maximum profit can be achieved by:
    Buying at prices[0] = 1
    Selling at prices[3] = 8
    Buying at prices[4] = 4
    Selling at prices[5] = 9
    The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
    
    

    Note:

    • 0 < prices.length <= 50000.
    • 0 < prices[i] < 50000.
    • 0 <= fee < 50000.

    代码一(DP)

    class Solution {
    public:
        int maxProfit(vector<int>& prices, int fee) {
            int profit=0;
            int hold[50001]={0};//持有股票
            int nohold[50001]={0};//不持有股票
            hold[0]=-prices[0];
            nohold[0]=0;
            for(int i=1;i<prices.size();i++)
            {
                nohold[i]=max(nohold[i-1],hold[i-1]+prices[i]-fee);
                hold[i]=max(hold[i-1],nohold[i-1]-prices[i]);       
            }
            return nohold[prices.size()-1];
        }
    };
    

    思考

    • 算法时间复杂度为O((n)),空间复杂度为O((n) ),这里空间复杂度其实可以优化,因为两个max函数中,如果nohold改变了即取了右边的值,hold只会取左边的值(大小关系),则每个状态其实只与前一前一天的状态有关,当天的nohold和hold并不会相互影响,所以可以只用一个变量存放nohold和hold,而不需要用数组。
    • 代码一是动态规划的思想。拆分成小问题是每一天的收益,每一天有两种情况,持有股票和不持有股票,它们的收益分别用hold和nohold来表示。
    • 当天持有股票的状态有两个可能的原因,一是昨天持有股票今天不变,二是昨天未持有,今天购入,那区分二者用一个max函数,选择收益最大的那种策略。转移方程为hold[i]=max(hold[i-1],nohold[i-1]-prices[i])。
    • 当天未持有股票的状态有两个可能的原因,一是昨天未持有股票今天不变,二是昨天持有,今天卖出,那区分二者用一个max函数,选择收益最大的那种策略。转移方程为nohold[i]=max(nohold[i-1],hold[i-1]+prices[i]-fee);。
    • 最后一天是不持有股票的,所以输出nohold的最后的值。

    代码二(贪心)

    class Solution {
    public:
        int maxProfit(vector<int>& prices, int fee) {
            int sell=0;
            int buy=0;
            int profit=0;
            for(int i=0;i<prices.size();i++)
            {
                if(buy==0)
                    buy=prices[i];
                else 
                {
                    if(sell==0)
                    {
                        if(prices[i]<buy)
                            buy=prices[i];
                        else if(prices[i]-buy>fee)
                            sell = prices[i];
                        else
                            continue;
                    }
                    else 
                    {
                        if(prices[i]<=sell-fee)
                        {
                            profit+=sell-buy-fee;
                            sell=0;
                            buy=prices[i];
                        }
                        else if(prices[i]>sell)
                            sell=prices[i];
                        else
                            continue;
                    }
                }
            }
            if(sell&&buy)
                profit+=sell-buy-fee;
            return profit;
        }
    };
    

    思考

    • 算法时间复杂度为O((n)),空间复杂度为O((1) )。
    • 代码二是贪心的思想。保证每一笔交易都是最大化收益,关键是卖出的时间点,只当价格低于sell-fee时卖出。
  • 相关阅读:
    bzoj 3238
    bzoj 3473 后缀自动机多字符串的子串处理方法
    bzoj 2998 第k小字串
    bzoj 3672 利用点分治将CDQ分治推广到树型结构上
    bzoj 3671 贪心
    NOIP模拟题——nan
    NOIP模拟题——kun(栈)
    hduP2586——How far away ?
    DP习题
    NOIP模拟题——来自风平浪静的明天
  • 原文地址:https://www.cnblogs.com/zuotongbin/p/10545921.html
Copyright © 2011-2022 走看看