leetcode
leetcode 2501 ~ 2550
价格递增的最大利润三元组 II

价格递增的最大利润三元组 II

难度:

标签:

题目描述

代码结果

运行时间: 280 ms, 内存: 24.9 MB


/*
 * Solution for LeetCode problem 2921: 价格递增的最大利润三元组 II using Java Streams
 * This approach leverages Java Streams to handle the operations more functionally.
 */

import java.util.stream.IntStream;

public class MaxProfitTripletStream {
    public int maxProfit(int[] prices) {
        int n = prices.length;
        if (n < 3) return 0;

        int[] leftMin = new int[n];
        leftMin[0] = prices[0];
        for (int i = 1; i < n; i++) {
            leftMin[i] = Math.min(leftMin[i - 1], prices[i]);
        }

        return IntStream.range(1, n - 1).flatMap(j ->
            IntStream.range(j + 1, n)
                .filter(k -> prices[j] > leftMin[j - 1] && prices[k] > prices[j])
                .map(k -> prices[k] - leftMin[j - 1])
        ).max().orElse(0);
    }

    public static void main(String[] args) {
        MaxProfitTripletStream solution = new MaxProfitTripletStream();
        int[] prices = {3, 1, 4, 1, 5, 9, 2, 6};
        System.out.println(solution.maxProfit(prices)); // Output should be the maximum profit
    }
}

解释

方法:

该题解采用了二分单调栈的方法来求解价格递增的最大利润三元组问题。首先,我们使用一个单调栈来维护一个由价格和利润组成的元组列表,确保随着价格的增加,相应的利润也是单调递增的。在遍历价格和利润数组时,我们尝试通过二分查找的方式找到当前价格能插入单调栈的位置,并根据这个位置更新可能的最大利润(通过之前的利润加上当前的利润)。第二次使用单调栈时,我们将DP值作为新的利润,以此来尝试更新最终的最大利润。

时间复杂度:

O(n log n)

空间复杂度:

O(n)

代码细节讲解

🦆
在题解中提到使用二分单调栈的方法,能否详细解释什么是单调栈以及它在这个问题中的具体作用是什么?
单调栈是一种特殊的栈结构,其中的元素按照单调递增或单调递减的顺序排列。在这个问题中,单调栈用于维护一个元组列表,其中每个元组包含一个价格和一个利润。这样,随着价格的增加,利润也保持递增。在这个场景中,单调栈帮助我们快速找到对于当前价格来说,之前可以获得的最高利润,从而计算当前组合的总利润,并进一步尝试更新最大利润。
🦆
你如何确定在单调栈中使用二分查找来插入元素是一个有效的策略?这种策略在所有情况下都适用吗?
在单调栈中使用二分查找是为了快速找到一个位置,使得新元素可以插入而不破坏栈的单调性。这种策略有效地减少了插入操作的时间复杂度,从O(n)降低到O(log n),因此在需要频繁插入且关心性能的场景中非常有用。然而,这种策略前提是栈内的元素按某种可比较的顺序排列,如果元素间没有明确的比较规则或者栈的更新操作非常频繁而且复杂,则可能不适用。
🦆
在题解中,提到了两次构建单调栈,这两次构建有何不同?第二次构建单调栈为什么要以DP值作为新的利润?
题解中第一次构建单调栈是基于初始的价格和利润,目的是为了计算每个位置可能得到的最大利润并存储到DP数组中。第二次构建单调栈时,使用DP数组中的元素作为新的利润,这是因为DP值代表了考虑之前所有可能选择后的最大利润。这样,第二次构建单调栈时,我们实际上在尝试基于之前已经计算好的最优解来更新可能的更高利润,从而找到整个问题的最终最大利润。
🦆
题解中提到了维护单调栈的过程中会删除一些元素,能否详细说明何时以及为什么需要进行这样的删除操作?
在维护单调栈时,如果新插入的元素(价格,利润)的利润比栈中某些元素的利润高,那么这些元素将不再有助于未来的最大利润计算,因为我们总可以选择新元素而获得更高的利润。因此,删除操作是为了保持栈的单调递增性质,确保每个元素都是对应价格下可能获得的最大利润,从而在每次查询时都能得到正确和最优的结果。

相关问题