LeetCode解题笔记 34 —— 188. 买卖股票的最佳时机 IV

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m940034240/article/details/89709733

题目

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

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

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

示例 1:

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

示例 2:

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

解法

class Solution {
    public int maxProfit(int k, int[] prices) {
        if(prices==null || prices.length<=1 || k<1){
            return 0;
        }
        List<Integer> listIn = new ArrayList<>();//记录有利润的买入价
        List<Integer> listOut = new ArrayList<>();//记录有利润的卖出价
        int p = -1;
        for(int i = 0; i < prices.length - 1; i++){
            if(prices[i]<prices[i+1]){
                if(p == -1){
                    p = prices[i];
                    listIn.add(p);
                }
            }else if(prices[i]>prices[i+1]){
                if(p != -1){
                    p = -1;
                    listOut.add(prices[i]);
                }
            }
        }
        if(p!=-1){
            listOut.add(prices[prices.length-1]); 
        } 
        if(k < listIn.size()){ //可交易次数小于有利润的交易次数
            while(listIn.size()> k){//移除或合并交易直到剩下最佳的k次交易
                removeOne(listIn,listOut);
            }
        }
        int sum = 0;
        for(int i = 0; i < listIn.size(); i++){
            sum = sum + listOut.get(i) - listIn.get(i);
        }
        return sum;
    }
    
    //移除一次利润最小的交易或合并两个相邻的交易
    private void removeOne(List<Integer> listIn,List<Integer> listOut){
        int fromIndex = 0;//要移除或合并的交易买入下标
        int toIndex = 0;//要移除或合并的交易卖出下标
        int price = Integer.MAX_VALUE;
        for(int i = 0; i < listIn.size();i++){
            if(listOut.get(i) - listIn.get(i) < price){
                fromIndex = i;
                toIndex = i;
                price = listOut.get(i) - listIn.get(i);
            }
            if(i < listIn.size() - 1){
                // (listOut.get(i) - listIn.get(i)) + (listOut.get(i+1) - listIn.get(i+1)) - (listOut.get(i+1) - listIn.get(i))
                int p = listOut.get(i) -  listIn.get(i+1);
                if(p < price){
                    fromIndex = i;
                    toIndex = i + 1;
                    price = p;
                }
            }
        }
        listIn.remove(toIndex);
        listOut.remove(fromIndex);
    }
}

猜你喜欢

转载自blog.csdn.net/m940034240/article/details/89709733
今日推荐