97 最大乘积区间问题 | 豆包MarsCode AI刷题

35 阅读3分钟

问题描述

小R手上有一个长度为 n 的数组 (n > 0),数组中的元素分别来自集合 [0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]。小R想从这个数组中选取一段连续的区间,得到可能的最大乘积。

你需要帮助小R找到最大乘积的区间,并输出这个区间的起始位置 x 和结束位置 y (x ≤ y)。如果存在多个区间乘积相同的情况,优先选择 x 更小的区间;如果 x 相同,选择 y 更小的区间。

注意:数组的起始位置为 1,结束位置为 n


测试样例

样例1:

输入:n = 5, arr = [1, 2, 4, 0, 8]
输出:[1, 3]

样例2:

输入:n = 7, arr = [1, 2, 4, 8, 0, 256, 0]
输出:[6, 6]

解题思路

  1. 初始化

    • max_product 初始化为负无穷大,确保任何乘积都能更新它。
    • startend 初始化为 0。
    • temp_start 初始化为 0。
    • product 初始化为 1。
  2. 遍历数组

    • 对于数组中的每个元素 arr[i]
      • 如果 arr[i] 为 0,表示当前区间结束。检查当前 product 是否大于 max_product,如果是,更新 max_product 和对应的区间 startend。然后重置 producttemp_start
      • 如果 arr[i] 不为 0,将 arr[i] 乘到 product 上。检查当前 product 是否大于 max_product,如果是,更新 max_product 和对应的区间 startend
  3. 处理最后一个区间

    • 在遍历结束后,检查最后一个区间的乘积是否大于 max_product,如果是,更新 max_product 和对应的区间 startend
  4. 返回结果

    • 返回 start + 1end + 1,因为题目要求的区间起始位置是从 1 开始的。

代码实现

from typing import List

def solution(n: int, arr: List[int]) -> List[int]:
    max_product = float('-inf')
    start = 0
    end = 0
    temp_start = 0
    product = 1
    zero_count = 0

    for i in range(n):
        if arr[i] == 0:
            if product > max_product:
                max_product = product
                start = temp_start
                end = i - 1
            product = 1
            zero_count += 1
            temp_start = i + 1
        else:
            product *= arr[i]
            if product > max_product:
                max_product = product
                start = temp_start
                end = i

    if product > max_product:
        max_product = product
        start = temp_start
        end = n - 1

    return [start + 1, end + 1]

if __name__ == "__main__": 
    print(solution(5, [1, 2, 4, 0, 8]) == [1, 3])
    print(solution(7, [1, 2, 4, 8, 0, 256, 0]) == [6, 6])

知识点总结

  1. 动态规划

    • 动态规划是一种通过将问题分解为子问题来解决复杂问题的方法。在这个问题中,可以使用动态规划来记录每个区间的乘积,并逐步更新最大乘积和对应的区间。
    • 动态规划通常涉及状态定义、状态转移方程和边界条件的处理。
  2. 滑动窗口

    • 滑动窗口是一种常见的算法技巧,用于在数组或字符串中找到满足特定条件的子数组或子字符串。在这个问题中,可以使用滑动窗口来动态调整区间的起始和结束位置,以找到最大乘积的区间。
    • 滑动窗口通常涉及两个指针(起始指针和结束指针),通过移动指针来调整窗口的大小。
  3. 贪心算法

    • 贪心算法是一种在每一步选择中都采取当前状态下最优的选择,以期望达到全局最优的算法。在这个问题中,可以使用贪心算法来选择当前乘积最大的区间。
    • 贪心算法通常需要证明其正确性,即每一步的最优选择能够保证最终结果的最优性。