PHP 求数组中最大乘积子数组

3次阅读

需同时维护当前最大值和最小值,因负数会使大小关系反转,如-10×(-2)=20可能成为新最大值;遇正数max扩大、min缩小,遇负数max/min可能由上轮min/max乘得,遇0则重置。

PHP 求数组中最大乘积子数组

要求数组中最大乘积子数组,关键在于处理负数和零带来的符号翻转问题。不能像最大和子数组那样只用一个变量记录当前最优值,必须同时跟踪当前最大值和最小值。

为什么需要同时维护最大值和最小值

负数会让大小关系反转:比如当前最小值是 -10,再乘一个负数 -2,就变成 20,反而成了新的最大值。因此每一步都要基于前一步的 max 和 min 来更新当前的 max 和 min。

  • 遇到正数:max 倾向于继续扩大,min 倾向于继续缩小(更小)
  • 遇到负数:max 可能由上一轮的 min × 当前负数得到,min 可能由上一轮的 max × 当前负数得到
  • 遇到 0:当前 max 和 min 都重置为 0,后续需重新开始

动态规划解法(空间优化版)

定义两个变量:curMax 表示以当前位置结尾的最大乘积,curMin 表示以当前位置结尾的最小乘积。遍历过程中不断更新全局最大值。

  • 初始化 curMax = curMin = globalMax = nums[0]
  • 从索引 1 开始遍历,对每个 nums[i] 计算三个候选值:nums[i]、curMax × nums[i]、curMin × nums[i]
  • curMax = max(三者),curMin = min(三者)
  • globalMax = max(globalMax, curMax)

例如数组 [2, 3, -2, 4]: i=1 → curMax=6, curMin=3 → globalMax=6 i=2 → curMax=6, curMin=-12(因为 -2×6)→ globalMax=6 i=3 → curMax=4(因为 4 > -12×4=-48 > 6×4=24?错!实际 4 > -48,但 6×4=24 更大 → curMax=24)→ globalMax=24

边界与特殊情况处理

空数组返回 0;单元素数组直接返回该元素;含多个负数时,偶数个负数可形成正乘积,奇数个则需舍弃最左或最右的一个负数(动态规划自动覆盖该逻辑)。

立即学习PHP免费学习笔记(深入)”;

  • 全负数组如 [-2,-3,-4]:最大乘积是 -2(子数组长度为 1),不是 -2×-3×-4=-24
  • 含零数组如 [2,0,3]:最大乘积是 max(2, 0, 3) = 3,不是 2×0×3=0
  • 推荐初始化 globalMax = nums[0],避免全负场景下误取 0

代码片段(php

$nums = [2, 3, -2, 4];<br>if (empty($nums)) {<br>  echo 0;<br>  exit;<br>}<br>$curMax = $curMin = $globalMax = $nums[0];<br>for ($i = 1; $i < count($nums); $i++) {<br>  $candidates = [$nums[$i], $curMax * $nums[$i], $curMin * $nums[$i]];<br>  $curMax = max($candidates);<br>  $curMin = min($candidates);<br>  $globalMax = max($globalMax, $curMax);<br>}<br>echo $globalMax; // 输出 6 或 24,取决于输入

text=ZqhQzanResources