LeetCode problem solving notes 34-188. The best time to buy and sell stocks IV

Keywords: less

subject

Given an array, its i-th element is the price of a given stock on day I.

Design an algorithm to calculate the maximum profit you can get. You can complete up to k transactions.

Note: you cannot participate in multiple transactions at the same time (you must sell the previous shares before you buy again).

Example 1:

Input: [2,4,1], k = 2
 Output: 2
 Explanation: buy on the first day (stock price = 2) and sell on the second day (stock price = 4). The exchange will get profit = 4-2 = 2.

Example 2:

Input: [3,2,6,5,0,3], k = 2
 Output: 7
 Explanation: buy on the second day (stock price = 2) and sell on the third day (stock price = 6). The exchange will get profit = 6-2 = 4.
Subsequently, buy on the 5th day (stock price = 0) and sell on the 6th day (stock price = 3), and the exchange will get profit = 3-0 = 3.

 

solution

class Solution {
    public int maxProfit(int k, int[] prices) {
        if(prices==null || prices.length<=1 || k<1){
            return 0;
        }
        List<Integer> listIn = new ArrayList<>();//Record the purchase price with profit
        List<Integer> listOut = new ArrayList<>();//Record the selling price with profit
        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()){ //The number of tradable transactions is less than the number of profitable transactions
            while(listIn.size()> k){//Remove or merge transactions until the best k transactions remain
                removeOne(listIn,listOut);
            }
        }
        int sum = 0;
        for(int i = 0; i < listIn.size(); i++){
            sum = sum + listOut.get(i) - listIn.get(i);
        }
        return sum;
    }
    
    //Remove one transaction with the lowest profit or merge two adjacent transactions
    private void removeOne(List<Integer> listIn,List<Integer> listOut){
        int fromIndex = 0;//Buying subscripts of transactions to be removed or consolidated
        int toIndex = 0;//Sale subscripts of transactions to be removed or consolidated
        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);
    }
}

Posted by fme on Tue, 19 Nov 2019 07:55:11 -0800