【Hot 100 刷题计划】 LeetCode 152. 乘积最大子数组 | C++ 动态规划 (绝妙 swap 翻转技巧)

LeetCode 152. 乘积最大子数组

📌 题目描述

题目级别:中等

给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续 子数组 (该子数组中至少包含一个数字),并返回该子数组所对应的乘积。

测试用例的答案是一个 32-位 整数。

  • 示例 1:

    输入: nums = [2,3,-2,4]

    输出: 6

    解释: 子数组 [2,3] 有最大乘积 6。

  • 示例 2:

    输入: nums = [-2,0,-1]

    输出: 0

    解释: 结果不能为 2, 因为 [-2,-1] 不是子数组(不连续)。


💡 破题思路:动态规划的"负负得正"陷阱

这道题和"最大子数组和"非常像,但乘法有一个致命的特殊性:负号的存在 。

一个极其小的负数,如果再乘上一个负数,会瞬间翻盘变成一个巨大的正数!

因此,我们不能只记录"当前的最大乘积",我们还必须同时记录"当前的最小乘积"(因为它有潜力在遇到下一个负数时变身成最大乘积)。

本解法的极客高光点 (Swap 魔法):

常规思路是在每次遍历时,同时用 nums[i]、nums[i] * max_dp、nums[i] * min_dp 三个数去求新的最大值和最小值,代码写起来非常繁琐。

但我们回归数学本质:当遇到一个负数时,乘积的大小关系会发生反转 。

所以,如果我们发现当前数字 nums[i] < 0,我们直接把维护的"当前最大值 mam"和"当前最小值 mim"互换位置 (swap) !

互换之后,我们就可以像处理正数一样,毫无顾忌地直接更新 mam 和 mim 了。这个思路极其优雅,堪称神来之笔。


💻 C++ 代码实现 (O(1) 空间极简版)

cpp 复制代码
class Solution {
public:
    int maxProduct(vector<int>& nums) {
        // mim 维护以当前元素结尾的最小乘积
        // mam 维护以当前元素结尾的最大乘积
        int mim = 1, mam = 1; 
        int res = INT_MIN; // 全局最大结果

        for (int i = 0; i < nums.size(); i ++ )
        {
            // 绝妙逻辑:遇到负数,乘积的极值属性反转,直接 swap!
            if (nums[i] < 0)
            {
                swap(mim, mam);
            }

            // 要么是从前面连乘过来的,要么就是从当前元素重新开始自己单干
            mim = min(nums[i], mim * nums[i]);
            mam = max(nums[i], mam * nums[i]);

            // 每次更新全局最大值
            res = max(res, mam);
        }

        return res;
    }
};
相关推荐
努力努力再努力wz14 小时前
【C++ 高阶系列】C++ 高性能网络编程:当 Reactor 遇见协程:从 epoll 回调到异步 MySQL,彻底打通任务挂起与恢复
网络·c++·mysql
晒太羊的猫14 小时前
hot100子串
java·算法·leetcode
霍霍的袁14 小时前
【C++11】左值右值引用与移动语义详细笔记(左值右值、右值引用、移动构造、移动赋值、引用折叠、万能转发)
c++·笔记·学习·visual studio
布莱克60515 小时前
C++ 中 unordered_set 与 unordered_map 有什么不同?一篇讲透
开发语言·c++·哈希
海清河晏11115 小时前
加油站问题
数据结构·算法·leetcode
鶴哥只手遮天15 小时前
AFSIM 2.9.0 深度解析:架构、原理与工程实践-第 1 章 项目全景与代码地图
c++
充值内卷15 小时前
C++单文件迷宫游戏:TauriCPP 开发全记录
开发语言·c++·游戏
Antruly15 小时前
C++ Web 开发选型漫谈:从 Drogon 到 libuvcpp + uvp,八个项目的定位、兼容性与务实排名
开发语言·前端·c++
another heaven16 小时前
【C/C++ C++ 新特性中的那些内存优化的特性】
c语言·开发语言·c++
ysu_031416 小时前
【C++ 进阶之路】(二)从内联函数到类与对象:深挖内存对齐、this 指针与三大默认成员函数
开发语言·数据结构·c++·笔记·面向对象·this