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

44 阅读4分钟

题目解析

问题理解

题目要求我们从给定的数组中找到一段连续区间的最大乘积,并返回该区间的起始和结束位置。数组中的元素都是2的幂次,因此乘积会迅速增大。我们需要特别注意乘积的计算和比较,以及如何处理0的情况。

思路

  1. 初始化变量

    • max_product:用于存储最大乘积,初始化为一个较小的值(如 -1)。
    • start 和 end:用于存储最大乘积区间的起始和结束位置,初始化为 -1
    • current_product:用于存储当前区间的乘积,初始化为 1
    • current_start:用于存储当前区间的起始位置,初始化为 0
  2. 遍历数组

    • 使用 for 循环遍历数组中的每个元素。
    • 如果当前元素是 0,重置 current_product 和 current_start
    • 否则,更新 current_product 为当前乘积乘以当前元素。
    • 如果 current_product 大于 max_product,更新 max_product 和区间 startend
    • 如果 current_product 等于 max_product,比较区间并更新 start 和 end
  3. 返回结果

    • 返回区间的起始和结束位置(从1开始计数)。

图解

假设我们有一个数组 [1, 2, 4, 0, 8],我们可以通过以下步骤找到最大乘积区间:

  1. 初始状态

    • max_product = -1
    • start = -1
    • end = -1
    • current_product = 1
    • current_start = 0
  2. 遍历数组

    • 第1个元素 1current_product = 1max_product = 1start = 0end = 0
    • 第2个元素 2current_product = 2max_product = 2start = 1end = 1
    • 第3个元素 4current_product = 8max_product = 8start = 0end = 2
    • 第4个元素 0:重置 current_product = 1current_start = 4
    • 第5个元素 8current_product = 8max_product = 8start = 4end = 4
  3. 最终结果

    • 最大乘积区间为 [1, 3],返回 [1, 3]

代码详解

    max_product = -1  # 初始化最大乘积为一个较小的值
    start, end = -1, -1  # 初始化最大乘积区间的起始和结束位置
    current_product = 1  # 当前区间的乘积
    current_start = 0  # 当前区间的起始位置

    for i in range(n):
        if data[i] == 0:
            # 如果遇到0,重置当前乘积和起始位置
            current_product = 1
            current_start = i + 1
        else:
            current_product *= data[i]  # 更新当前乘积
            if current_product > max_product:
                # 如果当前乘积大于最大乘积,更新最大乘积和区间
                max_product = current_product
                start = current_start
                end = i
            elif current_product == max_product:
                # 如果当前乘积等于最大乘积,比较区间
                if current_start < start or (current_start == start and i < end):
                    start = current_start
                    end = i

    return [start + 1, end + 1]  # 返回区间的起始和结束位置(从1开始计数)

if __name__ == "__main__":
    # Add your test cases here
    print(solution(5, [1, 2, 4, 0, 8]) == [1, 3])
    print(solution(7, [1, 2, 4, 8, 0, 256, 0]) == [6, 6])

总结

  • 时间复杂度:O(n),只需要遍历数组一次。
  • 空间复杂度:O(1),只使用了常数个额外的变量。
  • 关键点:处理0的情况,更新最大乘积和区间,以及返回结果时注意区间的起始和结束位置是从1开始计数。

感悟

1. 数组操作与遍历

  • 遍历数组:通过遍历数组,我们可以逐个处理数组中的元素,这是解决许多数组问题的基本方法。
  • 状态维护:在遍历过程中,我们需要维护一些状态变量(如当前乘积、最大乘积、当前区间的起始位置等),以便在遍历过程中进行更新和比较。

2. 特殊情况的处理

  • 处理0的情况:0会使得乘积变为0,因此我们需要在遇到0时重置当前乘积和起始位置。这教会我们在处理数组问题时,要特别注意特殊值(如0、负数等)对结果的影响。

3. 区间选择与更新

  • 区间选择:题目要求在多个区间乘积相同的情况下,优先选择起始位置更小的区间,如果起始位置相同,则选择结束位置更小的区间。这教会我们在处理区间问题时,如何根据题目要求选择合适的区间。
  • 区间更新:在遍历过程中,我们需要不断更新最大乘积及其对应的区间。这教会我们在动态更新过程中,如何保持状态的一致性和正确性。