📌  相关文章
📜  大小为 3 的递增子序列的最大乘积(1)

📅  最后修改于: 2023-12-03 14:51:42.082000             🧑  作者: Mango

寻找大小为3的递增子序列的最大乘积

在给定一个包含 n 个正整数的数组 nums 中,找出是否存在长度为 3 的递增子序列。

例如,给定 nums = [1, 2, 3, 4, 5],则存在长度为 3 的递增子序列 [1, 2, 3]。

现在要求寻找大小为 3 的递增子序列的最大乘积,即对于数组 nums,返回最大的 a[i] * a[j] * a[k],其中 0 ≤ i < j < k < n。

思路

为了寻找大小为 3 的递增子序列的最大乘积,我们可以遍历整个数组 nums,并在遍历的过程中维护两个值,即第一小、第二小、和第三小的值。

具体来说,我们用 three_max 表示到当前位置为止所有递增子序列末尾元素中的最大值,two_max 表示到当前位置为止所有长度为 2 的递增子序列末尾元素中的最大值,one_min 表示到当前位置为止所有长度为 1 的递增子序列末尾元素中的最小值。

在遍历过程中,对于元素 nums[i],我们更新 three_max、two_max 和 one_min 的值,如下所示:

  • 如果 nums[i] 比 three_max 大,那么我们找到了一个更长的递增子序列。此时我们可以返回 three_max,因为 three_max、two_max 和 one_min 一定组成了一个递增子序列。
  • 如果 nums[i] 比 two_max 大但比 three_max 小,那么我们更新 two_max 的值为 nums[i]。
  • 如果 nums[i] 比 one_min 大但比 two_max 小,那么我们更新 one_min 的值为 nums[i]。
  • 如果 nums[i] 比 one_min 还小,那么我们不需要更新任何值,因为当前位置为止最小的递增子序列末尾元素仍然是 one_min。

最后,如果找到了大小为 3 的递增子序列,我们返回 three_max * two_max * one_min,否则返回空值。

代码
def max_product(nums: List[int]) -> int:
    one_min = two_max = three_max = float('-inf')
    for num in nums:
        if num > three_max:
            one_min, two_max, three_max = two_max, three_max, num
        elif two_max < num <= three_max:
            one_min, two_max = two_max, num
        elif one_min < num <= two_max:
            one_min = num
        else:
            pass
    return three_max * two_max * one_min if one_min != float('-inf') else 0
复杂度分析
  • 时间复杂度:O(n),其中 n 是数组 nums 的长度。我们只需要遍历一次数组,每次更新 three_max、two_max 和 one_min 的时间复杂度是 O(1)。
  • 空间复杂度:O(1)。我们只需要维护 three_max、two_max 和 one_min 这三个变量。