zoukankan      html  css  js  c++  java
  • 【力扣】188. 买卖股票的最佳时机 IV

    给定一个整数数组 prices ,它的第 i 个元素 prices[i] 是一支给定的股票在第 i 天的价格。

    设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。

    注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

    示例 1:

    输入:k = 2, prices = [2,4,1]
    输出:2
    解释:在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2 。
    示例 2:

    输入:k = 2, prices = [3,2,6,5,0,3]
    输出:7
    解释:在第 2 天 (股票价格 = 2) 的时候买入,在第 3 天 (股票价格 = 6) 的时候卖出, 这笔交易所能获得利润 = 6-2 = 4 。
    随后,在第 5 天 (股票价格 = 0) 的时候买入,在第 6 天 (股票价格 = 3) 的时候卖出, 这笔交易所能获得利润 = 3-0 = 3 。
     

    提示:

    0 <= k <= 100
    0 <= prices.length <= 1000
    0 <= prices[i] <= 1000

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    // 时间复杂度 O(n * k)把从1 到 k的所有交易笔数的最大价格都求出来
        // 空间复杂度 O(n * k)
        public int maxProfit(int k, int[] prices) {
    
            //之前的算法是指定交易笔数,一笔或者两笔
            //那么当交易笔数变为非固定值时:应该怎么做呢?
            //想法也很简单,我们可以求出来固定交易笔数的最大的价格,当然也可以把从1 到 k的所有交易笔数的最大价格都求出来
            int length = prices.length;
    
            if(length < 2 || k < 1){
                return 0;
            }
            //想想最多有几次交易的机会 要么是长度的1/2 要么是k
            k = Math.min(length / 2,k);
            int [][] sell = new int[length][k+1];
            int [][] buy = new int[length][k+1];
    
            
            //设置初始值
            //首先是第一天买不买
            buy[0][0] = -prices[0];
            sell[0][0] = 0;
            //那像buy[0][2] 这种情况怎么处理呢? 第一天开始的时候,还不能交易2笔
                //sell[0][2]同理 
            for(int i = 1; i <= k; i++){
                buy[0][i] = Integer.MIN_VALUE / 2;
                sell[0][i] = Integer.MIN_VALUE / 2;
            }
            //现在还剩下buy[i][0]这种怎么处理?需要放到循环里处理,为什么要放到循环里,因为他也需要取最小值,看看几天一次交易也没有,哪个金额最小
    
    
            //举例:
                //sell[1][1] =  Math.max(buy[i-1][j-1]+prices[i],sell[i-1][j]); 
    
            //外层循环就是第几天
            for(int i = 1; i < length; i++){
                buy[i][0] = Math.max(buy[i - 1][0], sell[i - 1][0] - prices[i]);
    
                //内层循环就是交易笔数了
                for(int j = 1; j <= k ; j++){
                    //假设,到今天已经售卖了第j笔了
                        //有可能昨天买的,今天卖出 之前交易j-1笔,买卖完成才算一笔
                        //有可能之前售卖的笔数已经够j笔了
                    sell[i][j] =  Math.max(buy[i-1][j-1] + prices[i],sell[i-1][j]);
    
                    // 假设今天已经交易了j笔了
                        //有可能昨天已经交易j笔了
                        //有可能昨天已经卖出了j笔,今天买入
                    buy[i][j] = Math.max(sell[i-1][j] - prices[i],buy[i-1][j]);
                }
            }
            Arrays.sort(sell[length-1]);
            return sell[length-1][k];
        }
    public int maxProfit(int k, int[] prices) {
    
            // 时间复杂度 O(n * k)把从1 到 k的所有交易笔数的最大价格都求出来
            // 空间复杂度 O(k) //如何尽可能的压缩空间
            int length = prices.length;
    
            if(length < 2 || k < 1){
                return 0;
            }
            
            k = Math.min(length / 2,k);
            int [] sell = new int[k+1];
            int [] buy = new int[k+1];
    
            
            //设置初始值
            //首先是第一天买不买 ,不管第几天买,都是-prices[0]
            sell[0] = 0;
            Arrays.fill(buy,-prices[0]);
    
            //外层循环就是第几天
            for(int i = 1; i < length; i++){
                //内层循环就是交易笔数了
                for(int j = 1; j <= k ; j++){
                    sell[j] =  Math.max(buy[j] + prices[i],sell[j]); //卖出
                    buy[j] = Math.max(sell[j-1] - prices[i],buy[j]); //买入
                }
            }
            return sell[k];
        }
    一个入行不久的Java开发,越学习越感觉知识太多,自身了解太少,只能不断追寻
  • 相关阅读:
    HTML元素解释
    Java命名规范
    HDU 1058 Humble Numbers(DP,数)
    HDU 2845 Beans(DP,最大不连续和)
    HDU 2830 Matrix Swapping II (DP,最大全1矩阵)
    HDU 2870 Largest Submatrix(DP)
    HDU 1421 搬寝室(DP)
    HDU 2844 Coins (组合背包)
    HDU 2577 How to Type(模拟)
    HDU 2159 FATE(二维完全背包)
  • 原文地址:https://www.cnblogs.com/fengtingxin/p/14286798.html
Copyright © 2011-2022 走看看