Skip to content

Latest commit

 

History

History
201 lines (144 loc) · 5.55 KB

股票买卖汇总.md

File metadata and controls

201 lines (144 loc) · 5.55 KB

121. Best Time to Buy and Sell Stock (交易一次)

https://leetcode.com/problems/best-time-to-buy-and-sell-stock/

代码

class Solution {
    public int maxProfit(int[] prices) {
        if (prices == null || prices.length < 2)
            return 0;
        int max = 0;
        int low = prices[0];
        for (int day = 1; day < prices.length; day++) {
            max = Math.max(max, prices[day] - low);
            low = Math.min(low, prices[day]);
        }
        return max;
    }
}

122. Best Time to Buy and Sell Stock II (交易无限次)

https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/

代码

class Solution {
    public int maxProfit(int[] prices) {
        if (prices == null || prices.length < 2)
            return 0;
        int max = 0;
        for (int day = 1; day < prices.length; day++) {
            max += Math.max(prices[day] - prices[day-1], 0);
        }
        return max;
    }
}

123. Best Time to Buy and Sell Stock III (至多两次)

https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/

代码

class Solution(object):
    def maxProfit(self, prices):
        if not prices or len(prices) < 2:
            return 0
        n = len(prices)
        p1, p2 = [0] * n, [0] * n
        
        lowest = prices[0]
        for i in range(1, n):
            p1[i] = max(p1[i], prices[i] - lowest)
            lowest = min(lowest, prices[i])
        
        highest = prices[n - 1]
        for j in range(n-2, -1, -1):
            p2[j] = max(p2[j + 1], highest - prices[j])
            highest = max(highest, prices[j])
            
        maxProfit = 0
        for i in range(n):
            maxProfit = max(maxProfit, p1[i] + p2[i])
        
        return maxProfit

188. Best Time to Buy and Sell Stock IV (至多K次)

https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/

关键点

  • 动态规划,max[K][day] 表示截止到第 day 天一共交易 K 次的最大利润

  • 进一步优化(降维):因为第 K 次交易只与 K-1 次有关,所以只需要两个滚动数组记录 max[day] 即可。这里把上一步中的二维的DP降维成两个一维数组。

    • lastTransMax[day]前一次交易第 day 天的最大利润
    • currTransMax[day]当前交易到第 day 天的最大利润
  • DP方程:我们选择在第 day 天交易(即卖出,因为买进可看作是亏钱)或者不交易,即:

    currTransMax[day] = Math.max(maxRemaining + prices[day], currTransMax[day-1])

注意点

  • 如果我们发现 K 过大,即 K 大于交易天数的一半,则可看成是无限次交易,因为一次完整的交易最少也需要2天,一买一卖,那么 N 天最多也只能进行 N/2 次交易,所以K > N/2 的这种情况可以当成无限次交易来完成。参考 122. Best Time to Buy and Sell Stock II

代码

class Solution {
    public int maxProfit(int k, int[] prices) {
        // corner case
        if (k == 0 || prices == null || prices.length < 2)
            return 0;
        // check k if too large
        if (k > prices.length / 2) {
            int max = 0;
            for (int i = 1; i < prices.length; i++) {
                max += Math.max(prices[i]-prices[i-1], 0);
            }
            return max;
        }
        
        int days = prices.length;
        // 滚动数组
        int[] lastTransMax = new int[days];
        int[] currTransMax = new int[days];
        
        for (int trans = 1; trans <= k; trans++) {
            int maxRemaining = -prices[0];
            for (int day = 1; day < days; day++) {
                currTransMax[day] = Math.max(maxRemaining + prices[day], currTransMax[day-1]);
                maxRemaining = Math.max(maxRemaining, lastTransMax[day] - prices[day]);
            }
            lastTransMax = currTransMax;
            currTransMax = new int[days];
        }
        return lastTransMax[days-1];    
    }
}

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/

You are given an array prices where prices[i] is the price of a given stock on the ith day, and an integer fee representing a transaction fee.

Find the maximum profit you can achieve. You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction.

Note: You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again).

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.

Example 2:

Input: prices = [1,3,7,5,10,3], fee = 3
Output: 6

Constraints:

  • 1 < prices.length <= 5 * 104
  • 0 < prices[i], fee < 5 * 104

代码

class Solution {
    public int maxProfit(int[] prices, int fee) {
        int n = prices.length;
        int[][] f = new int[n + 1][2];
        int INT_MIN = Integer.MIN_VALUE;
        for (int i = 0; i < f.length; i++) 
            Arrays.fill(f[i], INT_MIN);
        f[0][0] = 0;
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            f[i][0] = Math.max(f[i - 1][0], f[i - 1][1] + prices[i - 1]);
            f[i][1] = Math.max(f[i - 1][1], f[i - 1][0] - prices[i - 1] - fee);
            ans = Math.max(ans, f[i][0]);
        }
        return ans;
    }
}