下面是 LeetCode 152. 乘积最大子数组 的 C++ 实现。思路与 Python / Rust 完全一致,我为你提供 LeetCode 标准写法 和 完整可运行示例,并额外补充一个防溢出安全版。
✅ 核心思路(简要回顾)
乘积与求和不同,遇到负数会翻转符号,遇到 0 会清零,因此:
- 必须同时维护
“imax”(以当前元素结尾的最大乘积)和
“imin”(最小乘积) - 遇到负数时,交换
“imax” 和
“imin” - 每一步允许从当前元素“重新开始”(
“max(x, imax * x)”) - 用
“ans” 记录全局最大值
✅ 解法一:LeetCode 标准写法(推荐)
对应 LeetCode 函数签名,使用
“int”,代码简洁直观。
#include
#include
using namespace std;
class Solution {
public:
int maxProduct(vector& nums) {
if (nums.empty()) return 0;
int imax = nums[0]; int imin = nums[0]; int ans = nums[0]; for (int i = 1; i < nums.size(); ++i) { int x = nums[i]; // 遇到负数,最大最小会反转,先交换 if (x < 0) { swap(imax, imin); } // 更新以当前位置结尾的最大/最小乘积 imax = max(x, imax * x); imin = min(x, imin * x); // 更新全局答案 ans = max(ans, imax); } return ans; }};
✅ 解法二:防溢出安全版(使用
“long long”)
虽然题目保证最终结果在
“int” 范围内,但中间乘法可能溢出
“int”(如
“2147483647 * 2”)。用
“long long” 存中间变量更安全。
#include
#include
using namespace std;
class Solution {
public:
int maxProduct(vector& nums) {
if (nums.empty()) return 0;
long long imax = nums[0]; long long imin = nums[0]; long long ans = nums[0]; for (int i = 1; i < nums.size(); ++i) { int x = nums[i]; if (x < 0) { swap(imax, imin); } imax = max((long long)x, imax * x); imin = min((long long)x, imin * x); ans = max(ans, imax); } return (int)ans; }};
✅ 完整可运行测试代码
#include
#include
#include
using namespace std;
class Solution {
public:
int maxProduct(vector& nums) {
if (nums.empty()) return 0;
int imax = nums[0]; int imin = nums[0]; int ans = nums[0]; for (int i = 1; i < nums.size(); ++i) { int x = nums[i]; if (x < 0) { swap(imax, imin); } imax = max(x, imax * x); imin = min(x, imin * x); ans = max(ans, imax); } return ans; }};
int main() {
Solution sol;
vector<vector> testCases = {
{2, 3, -2, 4},
{-2, 0, -1},
{-2, 3, -4},
{-1},
{0, 2, 0, 3, 4},
{-4, -3, -2}
};
for (auto& nums : testCases) { int result = sol.maxProduct(nums); cout << "输入: ["; for (size_t i = 0; i < nums.size(); ++i) { cout << nums[i]; if (i != nums.size() - 1) cout << ", "; } cout << "] -> 输出: " << result << endl; } return 0;}
输出结果:
输入: [2, 3, -2, 4] -> 输出: 6
输入: [-2, 0, -1] -> 输出: 0
输入: [-2, 3, -4] -> 输出: 24
输入: [-1] -> 输出: -1
输入: [0, 2, 0, 3, 4] -> 输出: 12
输入: [-4, -3, -2] -> 输出: 12
📊 复杂度分析
指标 数值
时间复杂度 O(n) — 单次遍历
空间复杂度 O(1) — 仅用常数变量
🔧 C++ 实现要点
要点 说明
“std::swap” 交换两个同类型变量,头文件
“” 或直接使用(C++11 起在
“” 中,但通常
“” 已包含)
“std::max” /
“std::min” 需要
“” 头文件
整数溢出
“int” 相乘可能溢出,若面试或工程环境严谨,建议用
“long long” 存
“imax” /
“imin”
空数组判断 LeetCode 保证
“nums.length >= 1”,但防御性编程可加上
“empty()” 判断
💡 一句话总结
乘积最大子数组 = 维护最大/最小乘积 + 遇负交换 + 允许重启 + O(1) 空间
需要我补充分治/线段树解法,或者帮你对比 C++ / Rust / Python 三种实现的性能差异吗?😊