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

125 阅读3分钟

攻克 “最大乘积问题”:算法思路与代码实现全解析 在编程与算法领域,“最大乘积问题” 是一道经典且饶有趣味的题目,它频繁现身于各类算法竞赛、面试环节,考验着开发者对数字规律、贪心策略或动态规划思想的灵活运用。接下来,将深入剖析该问题的内涵、解题策略,并附上代码示例助你吃透要点。 一、问题剖析 “最大乘积问题” 通常描述如下:给定一个正整数数组(或正整数序列),要求从中选取若干个数字(可重复选取或按特定规则选取),使得它们的乘积最大。例如,给定数组 [2, 3, -2, 4],在可选取数组中任意多个数(不限制选取次数)组成乘积的规则下,要找出能得到最大乘积的组合方式及乘积结果。这看似简单的规则,背后蕴含多种复杂情况,如数组中有正、负、零元素交织,选取策略受元素正负性、数量影响极大。 二、解法探究 贪心策略解法 当数组元素全为正数时,贪心策略清晰直观 —— 尽可能多地选取最大的正数相乘即可达最大乘积。但数组含负数、零元素时就需巧妙构思。核心思路是记录当前遇到的最大正数、最小负数(绝对值最大的负数)乘积,因为乘一个负数会改变乘积大小性质,负数乘负数得正数。一次遍历数组,不断更新最大、最小乘积记录,过程如下: 初始化 max_product(最大乘积)、min_product(最小乘积)、result(最终结果)都设为数组首元素,遍历数组,设当前元素为 nums[i]。 暂存当前 max_product 值为 prev_max,更新 max_product = max(nums[i], nums[i] * max_product, nums[i] * min_product),更新 min_product = min(nums[i], nums[i] * prev_max, nums[i] * min_product),这一步考虑了乘正数、负数及单独选当前数三种情况。 result 更新为 max(result, max_product),遍历完整个数组,result 存下全局最大乘积。 动态规划解法 用动态规划应对,定义状态至关重要。设 dp_max[i] 表示前 i 个元素能构成的最大乘积,dp_min[i] 表示最小乘积。状态转移方程推导基于当前元素选取与否及与之前乘积关联: 基础情况:dp_max[0] = dp_min[0] = nums[0],首个元素自身构成初值。 对于 i > 0,dp_max[i] = max(nums[i], nums[i] * dp_max[i - 1], nums[i] * dp_min[i - 1]),类似贪心考虑选新数、与之前最大、最小乘积运算;dp_min[i] = min(nums[i], nums[i] * dp_max[i - 1], nums[i] * dp_min[i - 1]),最终答案是 dp_max 数组最大值,通过两重循环填充 dp 数组求解。 三、代码示例 贪心算法代码(Python) python 复制 def max_product(nums): if not nums: return 0 max_product_ending_here = min_product_ending_here = max_product_so_far = nums[0] for num in nums[1:]: prev_max = max_product_ending_here max_product_ending_here = max(num, num * max_product_ending_here, num * min_product_ending_here) min_product_ending_here = min(num, num * prev_max, num * min_product_ending_here) max_product_so_far = max(max_product_so_far, max_product_ending_here) return max_product_so_far 动态规划代码(Java) java 复制 public class MaxProduct { public static int maxProduct(int[] nums) { int[] dp_max = new int[nums.length]; int[] dp_min = new int[nums.length]; dp_max[0] = dp_min[0] = nums[0]; int max_product = nums[0]; for (int i = 1; i < nums.length; i++) { dp_max[i] = Math.max(nums[i], Math.max(nums[i] * dp_max[i - 1], nums[i] * dp_min[i - 1])); dp_min[i] = Math.min(nums[i], Math.min(nums[i] * dp_max[i - 1], nums[i] * dp_min[i - 1])); max_product = Math.max(max_product, dp_max[i]); } return max_product; } public static void main(String[] args) { int[] nums = {2, 3, -2, 4}; System.out.println(maxProduct(nums)); } } 上述代码简洁实现对应解法,贪心简洁、动态规划严谨,助你理解运用。攻克 “最大乘积问题”,能夯实基础、提升思维,应对多变算法挑战。不断练习、拓展思路,算法之旅将更精彩。