当前位置: 面试刷题>> 数组剔除元素后的乘积 (经典算法题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代码示例** 可以用类似逻辑实现,但具体语法和函数库调用会有所不同。由于篇幅限制,这里不再详细展开。