zoukankan      html  css  js  c++  java
  • leetcode188

    Say you have an array for which the ith element is the price of a given stock on day i.
    Design an algorithm to find the maximum profit. You may complete at most k transactions.
    Note:
    You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
    Example 1:
    Input: [2,4,1], k = 2
    Output: 2
    Explanation: Buy on day 1 (price = 2) and sell on day 2 (price = 4), profit = 4-2 = 2.
    Example 2:
    Input: [3,2,6,5,0,3], k = 2
    Output: 7
    Explanation: Buy on day 2 (price = 2) and sell on day 3 (price = 6), profit = 6-2 = 4.
    Then buy on day 5 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.



    DP。O(n^3)
    定义: dp[i][j] 为最多允许交易i次,从0~j天,你可能获得的最大利润。
    初始化:第一行都为0(不允许交易),第一列都为0(只有一天不能卖)
    递推公式:dp[i][j] = max(dp[i][j - 1], prices[j] - prices[m] + T[I - 1][m]),对所有在[0, j]的m。
    解释:每一步,要么不卖股票(dp[i][j - 1]。 要么卖股票,而且这次卖的股票是从第m天买的,那么m天它的操作维度要让操作次数下降一级)。因为允许交易次数是从0开始不断向上刷新到k的,所以正确性有所保证。

    优化:
    1.解决MLE。当k很大的时候为了节省空间,使用滚动数组。毕竟每次只依赖前一行的信息。
    2.解决TLE。当k远大于天数的时候,开那么大的数组刷新出下面很多行一样的数据就没意义了,退化回问题II,上升区间段都计入最终利润。

    实现:

    class Solution {
        public int maxProfit(int k, int[] prices) {
            if (prices == null || prices.length == 0) {
                return 0;
            }
            // P2: 解决TLE。当k远大于天数的时候,开那么大的数组刷新出下面很多行一样的数据就没意义了,退化回问题II。
            if (k > prices.length) {
                return quickSolve(prices);
            }
            
            // P1: 解决MLE。当k很大的时候为了空间也可以用滚动数组。毕竟每次只依赖前一行的信息。
            // int[][] dp = new int[k + 1][prices.length + 1];
            int[][] dp = new int[2][prices.length + 1];
            
            for (int j = 0; j < dp[0].length; j++) {
                dp[0][j] = 0;
            }
            
            for (int i = 0; i < dp.length; i++) {
                dp[i][0] = 0;
            }
            
            for (int i = 1; i <= k; i++) {
                for (int j = 1; j < dp[0].length; j++) {
                    dp[i % 2][j] = Math.max(dp[i % 2][j], dp[i % 2][j - 1]);
                    for (int m = 1; m <= j; m++) {
                        dp[i % 2][j] = Math.max(dp[i % 2][j], prices[j - 1] - prices[m - 1] + dp[(i - 1) % 2][m]);
                    }
                }
            }
            
            return dp[k % 2][dp[0].length - 1];
        }
        
        private int quickSolve(int[] prices) {
            int profit = 0;
            for (int i = 1; i < prices.length; i++) {
                if (prices[i] > prices[i - 1]) {
                    profit += prices[i] - prices[i - 1];
                }
            }
            return profit;
        }
    }
  • 相关阅读:
    我爱Java系列之---【SpringBoot打成war包部署】
    279. Perfect Squares
    矩阵dfs--走回路
    112. Path Sum
    542. 01 Matrix
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    Invert Binary Tree
    563 Binary Tree Tilt
    145 Binary Tree Postorder Traversal
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/9697603.html
Copyright © 2011-2022 走看看