• 714.买卖股票的最佳时机含手续费


    给定一个整数数组 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

    解决这个问题的关键是要知道什么时候该卖出,利润就等于卖出时价格减去之前遍历到的最小值再减去手续费,利润很好计算。

    那么怎么判断是该持有还是该卖出呢?

    首先从第二个数开始遍历,如果它比第一个数小,那我们就不买第一天的,买第二天的股票(这个时候更新最小值min)。

    再来继续遍历,如果第三天的价格比第二天的高呢?(这个时候更新最大值max)这个时候卖不卖?无论卖或者不卖都让人为难,因为你不知道后面价格是不是会更高。所以我们是否卖出股票应该由接下来的一天决定。

    所以我们看第四天的,如果第四天比第三天还高,那我们就继续观望(继续更新max)。

    第五天终于跌了,跌多少的时候卖出呢?假设之前的最小值为a,第四天(也就是跌之间的最大值)的价格为b,跌了之后价格为c,第二次卖出时价格为d。那么不卖出,也就是从a-d只交易一次利润为p1 = (d-a-fee),卖出,也就是交易两次利润为p2 =(b-a+d-c-2*fee),当交易两次利润比一次利润大时,我们在下跌的时候就应该卖出,p2-p1 = b-c-fee>0,也就是b-c>fee。所以当跌了的价格超过手续费时我们就应该卖出,这样就能进行多次交易获得更大的利润。

    当遍历到末尾时,只要利润大于0就应该卖出。

    class Solution {
        public int maxProfit(int[] prices, int fee) {
        	int res = 0;
        	int min = prices[0];
        	int max = prices[0];
        	int cur = 0;
        	//min记录遍历到的最小值,max记录遍历到的最大值
        	//这个最难在于求什么时候卖出,取最小值为购买点,最大值减最小值即为利润
        	for(int i = 1; i < prices.length; i++) {
        		min = Math.min(min, prices[i]);
        		max = Math.max(max, prices[i]);
        		cur = Math.max(cur, prices[i] - min - fee);
                //由上述公式推导得,当下跌超过手续费时,就应该卖出
        		if(max - prices[i] > fee) {
        			res += cur;
        			cur = 0;
        			min = prices[i];
        			max = prices[i];
        		}
        	}
        	res += cur;
        	return res;
        }
    }
    
  • 相关阅读:
    [Algorithms] Counting Sort
    [LeetCode] Sort Colors
    [LeetCode] Contains Duplicate III
    [LeetCode] Contains Duplicate
    [LeetCode] Two Sum II
    [LeetCode] Linked List Cycle II
    [LeetCode] Linked List Cycle
    [LeetCode] Longest Palindromic Substring
    [LeetCode] Two Sum
    [LeetCode] Rectangle Area
  • 原文地址:https://www.cnblogs.com/Jiewl/p/12666686.html
Copyright © 2020-2023  润新知