伴学笔记 | 豆包MarsCode AI刷题

49 阅读4分钟

一、题目解析

题目描述
我们需要找到一个数组中乘积最大的连续子区间,返回其起始和结束位置。特别的:

  1. 如果数组包含多个区间的最大乘积相同,则优先选择起始位置更小的区间。
  2. 如果起始位置也相同,则选择结束位置更小的区间。

思路梳理

  1. 动态规划思想:

    • 在遍历数组的过程中,实时维护以当前位置为结尾的最大乘积和最小乘积。
    • 因为负数的存在,最小乘积可能在乘以负数后转为最大乘积。
    • 当遇到 0 时,所有乘积重置为 1,区间重新开始。
  2. 贪心选择:

    • 每次更新最大乘积时,记录对应的区间起止位置。
    • 如果新找到的乘积与已记录的最大值相同,则根据题目要求选择区间。

代码详解

def solution(n: int, arr: list[int]) -> list[int]:
    # 初始化变量,用于记录最大乘积及其对应的区间起点和终点
    max_product = 0  # 最大乘积
    start_idx = 0    # 最大乘积区间的起始位置
    end_idx = 0      # 最大乘积区间的结束位置

    current_max = 1  # 当前的最大乘积
    current_min = 1  # 当前的最小乘积
    temp_start = 0   # 临时记录当前区间的起点

    for i in range(n):
        if arr[i] == 0:  # 遇到0时,重置乘积,重新开始
            current_max = 1
            current_min = 1
            temp_start = i + 1  # 区间重新从下一位开始
            continue
        
        # 计算包括当前元素的最大乘积和最小乘积
        temp_max = current_max * arr[i]
        temp_min = current_min * arr[i]
        current_max = max(arr[i], temp_max, temp_min)
        current_min = min(arr[i], temp_max, temp_min)
        
        # 更新最大乘积以及对应的区间
        if current_max > max_product:
            max_product = current_max
            start_idx = temp_start
            end_idx = i
        elif current_max == max_product:
            # 如果乘积相同,优先选择起点更小的区间
            if temp_start < start_idx or (temp_start == start_idx and i < end_idx):
                start_idx = temp_start
                end_idx = i

    return [start_idx + 1, end_idx + 1]

# 示例测试
print(solution(5, [1, 2, 4, 0, 8]))  # 输出:[1, 3]
print(solution(7, [1, 2, 4, 8, 0, 256, 0]))  # 输出:[6, 6]
print(solution(6, [0, 0, 1, 2, 4, 8]))  # 输出:[3, 6]

二、知识总结

  1. 动态规划思想的灵活性:

    • 本题通过动态更新以当前位置为终点的最大值和最小值,避免暴力枚举所有区间,大幅优化了时间复杂度。
  2. 处理特殊情况(如零值)的技巧:

    • 遇到零值时,直接重置乘积,起点从下一位重新开始。
  3. 维护多个变量:

    • 最大值和最小值的同步更新是动态规划中的常见模式,适用于包含负数或其他复杂规则的情况。

对其他入门同学的建议:

  • 通过画图帮助理解最大值和最小值如何在数组中动态变化。
  • 练习多个类似问题(如最大子数组和问题)以加深对动态规划的理解。

三、学习计划

  1. 制定刷题计划:

    • 每天练习 2-3 道动态规划和滑动窗口类问题,循序渐进提升难度。
    • 针对错题,重新审视解题思路,并对关键知识点进行总结。
  2. 利用错题进行针对性学习:

    • 记录每道错题的错误原因(思路不清晰、实现有误等)。
    • 重新手写代码并测试更多边界情况,确保完全理解。

四、工具运用

  1. AI 刷题工具与知识点笔记结合:

    • 在豆包MarsCode AI中搜索相关题目,获取解题提示和代码模板。
    • 针对错题,利用AI生成更详细的解析和学习建议。
  2. 整合学习资源:

    • 配合参考《算法导论》或其他算法书籍中的相关章节,对涉及的数学推导进行深入学习。
    • 借助在线可视化工具(如动态规划可视化网站)直观理解算法流程。

五、总结

最大乘积区间问题不仅考验对动态规划的理解,还涉及对边界情况的处理和细节优化。通过刷题工具和学习资源的结合,持续练习和总结可以帮助快速提升编程能力。希望这份笔记对你的学习有所帮助!