当前位置: 面试刷题>> 数组剔除元素后的乘积 (经典算法题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代码示例

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代码示例 可以用类似逻辑实现,但具体语法和函数库调用会有所不同。由于篇幅限制,这里不再详细展开。

推荐面试题