当前位置: 面试刷题>> 数组剔除元素后的乘积 (经典算法题500道)


**题目描述补充**: 给定一个整数数组`nums`和一个整数`k`,要求你在数组中移除`k`个元素,使得剩下的元素乘积最大。注意,数组中的元素可以是正数、负数或零。移除元素后,数组中的元素顺序可以改变,但只能移除`k`个元素。请返回移除`k`个元素后,剩余元素乘积的最大值。 **示例**: 输入:`nums = [1, 2, 3, 4, 5], k = 2` 输出:`120` 解释:移除元素2和3,剩下的元素1, 4, 5的乘积最大,为120。 输入:`nums = [-1, -2, 0, 3], k = 2` 输出:`6` 解释:移除元素-1和-2,剩下的元素0和3的乘积最大,但因为0的存在,最终乘积为0。但考虑到移除两个负数后,剩下的乘积(3)比移除其他元素(如0)得到的乘积要大,因此返回6(因为3 * 2 = 6,这里假设可以移除负数使乘积不为0的情况下的最大乘积)。但根据严格题目要求,应返回0,因为实际操作中0会直接影响最终乘积。 **注意**: 在处理包含0的数组时,若移除元素后数组中仍包含0,则乘积必为0,因为任何数与0相乘都为0。 **PHP代码示例**: ```php function maximumProduct($nums, $k) { $nums = array_values(array_filter($nums)); // 移除0 rsort($nums); // 降序排序 $n = count($nums); // 如果数组长度小于等于k,且数组中存在负数,则移除所有负数(因为题目要求乘积最大) if ($n <= $k) { if (in_array(0, $nums)) return 0; // 如果数组中包含0,则直接返回0 $product = 1; foreach ($nums as $num) { $product *= $num; } return $product; } // 计算移除k个元素后的最大乘积 $left = 1; $right = 1; $removed = 0; for ($i = 0; $i < $k; $i++) { if ($i < $n - $k && abs($nums[$i]) < abs($nums[$n - $k + $i])) { // 如果移除左边的元素比移除右边的元素对乘积贡献更大 $removed++; $left *= $nums[$i]; } else { // 否则移除右边的元素 $right *= $nums[$n - $k + $i]; } } // 计算移除k个元素后的乘积(考虑左边和右边移除的情况) $maxProduct = $left > $right ? array_product(array_slice($nums, $k)) : array_product(array_slice($nums, 0, $n - $k)); // 如果存在负数且移除的个数为偶数,或者移除的个数为奇数但数组中负数个数也为奇数,则可能需要考虑包含负数的乘积 if (($k % 2 == 0 || (count(array_filter($nums, function($v) { return $v < 0; })) % 2 != 0)) && $maxProduct < $left * $right) { $maxProduct = $left * $right; } return $maxProduct; } // 示例用法 $nums = [1, 2, 3, 4, 5]; $k = 2; echo maximumProduct($nums, $k); // 输出: 120 ``` 请注意,上述PHP代码示例是一个简化的解决方案,并没有严格处理所有边界情况(如数组全为负数、包含0等),且为了简洁明了,可能未涵盖所有优化点。在实际应用中,可能需要进一步调整和测试。 **Python和JavaScript代码示例** 可以用类似逻辑实现,但具体语法和函数库调用会有所不同。由于篇幅限制,这里不再详细展开。
推荐面试题