买入和卖出两次股票

时间:2017-04-28 17:16:02

标签: algorithm language-agnostic dynamic-programming puzzle

我正在努力理解这个problem,当我被允许最多两次购买/卖出股票时,我需要找出最大利润。提供的解决方案讨论了从左到右维护价格差异阵列,这对我来说很有意义。然而,这篇文章还讨论了从右到左维持另一系列价格差异的问题,我无法理解这种逻辑,因为在第一次交易之后,这会产生利润。

Prices= [1, 4, 5, 7, 6, 3, 2, 9]
left  = [0, 3, 4, 6, 6, 6, 6, 8]
right = [8, 7, 7, 7, 7, 7, 7, 0]
max_profit = 13

2 个答案:

答案 0 :(得分:3)

您提到的解决方案中有两个数组的事实与允许仅使用2个事务的问题约束有关。

同样如上所述,交易不应插入 - 一个交易应该在另一个交易之前(左边)(将在右边)。

更具体地说,提出的解决方案中的两个数组代表如下:

  • left [i] =在区间[0,i]中买入和卖出可以做出的最佳交易。如果在时间j进行销售(j在[0,i]中),则应该以0到j的最低价格进行购买。

  • right [i] =在区间[i,n-1]中通过买卖进行的最佳交易。如果在时间j完成购买(在[i,n-1]中使用j),则应以从j到n-1的最高价格进行销售。

所有需要找到的是两个交易的良好分离点 i 。然后最好的组合将涉及剩余利润[i] +右[i],这可以通过尝试所有可能的 i 值来找到。

答案 1 :(得分:0)

您可以像DP那样解决问题,在不买卖股票的情况下进行首次设定,使首次获利为零,并按相同顺序获利

仅进行一次交易

跟踪数组并保持与先前价格的最小值,最大利润为最大值-数组中的最小值。所以问题基本上是在数组中找到最大值和最小值,而差将是最大利润,在这里,我们只是更新利润数组,直到在特定日期进行交易或没有交易之前的最大利润是多少。该数组将用作进一步事务中的数据使用要求。

// Condition for the only one transaction is possible
       for (int i = 1; i < n; i++) {
         min = Math.min(price[i - 1], min);
           profit[i] = Math.max(profit[i - 1], price[i] - min);
        }

如果最多可以进行两次交易

现在,这里的事情很棘手,我们只需要跟踪先前为获得最大利润而进行的任何计算,直到k-1交易的数据(此处k = 2)为止。对于任何数量的事务,该问题都可以成为动态问题。

profit for a particular day is = max{ if no transaction is made (Then previous max profit, ie profit[i - 1]),
previous_profit + Max of sale possible{present price - all previous price(i,i-1,...0)) 

对于k = 2

//   Condition for at most two transaction is possible
        for (int i = 1; i < n; i++) {
           max = Math.max(max, profit[i] - price[i]);
             profit[i] = Math.max(profit[i - 1], max + price[i]);
        }

这是k笔交易的通用代码 我们只需要两个数组来跟踪先前的利润值并在每次迭代时覆盖。也可以使用2-D数组完成此操作,但我们不需要任何以前的数据,因此我使用了偶数和正数的数据数组来完成

   package DynamicProblems;

    public class StockSales {

        private static int maxProfit(int price[], int n, int k) {
            int currentProfit[] = new int[n];
            int previousProfit[];
            int evenProfit[] = new int[n];
            int oddProfit[] = new int[n];

            for (int t = 0; t <= k - 1; t++) {
                int max = Integer.MIN_VALUE;
                if (t % 2 == 1) {
                    currentProfit = oddProfit;
                    previousProfit = evenProfit;
                } else {
                    currentProfit = evenProfit;
                    previousProfit = oddProfit;
                }

                for (int i = 1; i < n; i++) {
                    max = Math.max(max, previousProfit[i - 1] - price[i - 1]);
                    currentProfit[i] = Math.max(currentProfit[i - 1], max + price[i]);
                }
            }
            return currentProfit[n - 1];
        }

        public static void main(String args[]) {
            int price[] = {3, 4, 10, 103};
            int k = 1;
            int n = price.length;
            System.out.println("\nMaximum Profit = " + maxProfit(price, n, k));
        }
    }