买卖股票两次

Buy and Sell stocks twice

我正在努力理解这个 problem,我需要在允许我最多 buy/sell 股票两次时找出最大利润。提供的解决方案讨论了从左到右维护价格差异数组,这对我来说很有意义。然而,post 还谈到了维护另一个从右到左的价差数组,我无法理解为什么在第一笔交易后会获利的逻辑。

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 个事务的问题的约束有关。

同样规定,交易不应该被插入——一个交易应该在另一个交易之前(在左边)另一个(将在右边) .

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

  • left[i] = 在区间[0,i]内买入卖出能做出的最佳交易。如果在时间 j 卖出(j 在 [0, i] 中),则应该在 0 到 j 的最低价处买入。

  • right[i] = 在区间[i,n-1]内买入卖出所能做出的最佳交易。如果在时间 j 买入(j 在 [i, n-1] 中),卖出应该以从 j 到 n-1 的最高价完成。

所有需要找到的是两个事务的良好分离点 i。那么最佳组合将涉及利润 left[i] + right[i],这可以通过尝试所有可能的 i 值来找到。

你可以像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笔交易的通用代码 我们只需要两个数组来跟踪以前的利润值并在每次迭代时覆盖。它也可以使用二维数组完成,但我们不需要任何以前的数据所以我用偶数和正数据数组

   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));
        }
    }