LeetCode | Best Time to Buy and Sell Stock III

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 two transactions.

Note: You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

要求:最多进行两次transaction,且同时只能持有一只股票。 tags:dynamic programming

解法一:

基本的想法:将数组分为前、后两个部分,分别用Best Time to Buy and Sell Stock I的方法来求解两个部分的最大收益,再求和。
通过N次数组划分之后,选出最大的总利润(提示超时。。。。。)

public class Solution {
    public int profit(int[] prices, int start, int end){  //Best Time to Buy and Sell Stock I 的解法
        if(end <= start) return 0;  
        int maxProfit = 0;  
        int min_price = prices[start];  
        for(int i=start; i<=end; i++){  
            if(prices[i]<min_price) min_price=prices[i];      
            if(prices[i]-min_price > maxProfit) maxProfit=prices[i]-min_price;  
        }  
        return maxProfit;  
    }
    
    public int maxProfit(int[] prices) {       //leetcode函数,实现对数组的N次划分
        if(prices.length <= 1) return 0;
        
        int maxProfit = 0;
        for(int i=0; i<prices.length; i++){
            int sum_profit = profit(prices, 0, i) + profit(prices, i+1, prices.length-1);
            if(maxProfit < sum_profit) maxProfit = sum_profit;
        }
        return maxProfit;
    }
}

解法二:

profit_0_i表示从0至i天所能获得的最大利润
profit_i_n表示从i至n天所能获得的最大利润
举例:prices = {2 1 8 3 5 9},则:
  profit_0_i = {0 0 7 7 7 8},填充时从左向右遍历,总是取已知最低价格min_price,然后用prices[i]-min_price来判断[0-i]区间能获得的最大收益
  profit_i_n = {8 8 6 6 4 0},填充时从右向左遍历,总是取已知最高价格max_price,然后用max_price-prices[i]来判断[i-n]区间能获得的最大收益
 则 max{ profit_0_i[i] + profit_i_n[i] } = 7 + 6 = 13 即为最大收益

public class Solution {
    public int maxProfit(int[] prices) {       
        if(prices.length <= 1) return 0;
        
        int[] profit_0_i = new int[prices.length];     //记录从0至i能获得的最大收益
        int[] profit_i_n = new int[prices.length];     //记录从i至n能获得的最大收益
        
        //求解填充数组profit_0_i
        int temp_1 = 0;
        int min_price = prices[0];
        for(int i=0; i<prices.length; i++){       //同Best Time to Buy and Sell Stock I 中的方法
            if(prices[i] < min_price) min_price = prices[i];
            if(prices[i]-min_price > temp_1) temp_1 = prices[i] - min_price;
            profit_0_i[i] = temp_1;
        }
        
        //求解填充数组profit_i_n
        int temp_2 = 0;
        int max_price = prices[prices.length-1];
        for(int j=prices.length-1; j>=0; j--){   //同Best Time to Buy and Sell Stock I 中的方法
            if(prices[j] > max_price) max_price = prices[j];
            if(max_price-prices[j] > temp_2) temp_2 = max_price - prices[j];
            profit_i_n[j] = temp_2;
        }
         
        //找最大的收益和
        int maxProfit = 0;
        for(int k=0; k<prices.length; k++){       //找最大的对应项之和
            int temp = profit_0_i[k] + profit_i_n[k];
            if(temp > maxProfit) maxProfit = temp;
        }
        return maxProfit;
    }
}



原文地址:https://www.cnblogs.com/dosmile/p/6444459.html