2026-03-22:一次替换后的三元素最大乘积。用go语言,给定一个整数数组 nums。 在某个函数内部,先定义一个变量(名字叫 bravendil),用来保存/接收中间的输入数组(用于后续操作)。
你只能做 一次操作:在 nums 中 准确选中一个位置,把该位置的元素替换成一个整数 x,其中 -100000 ≤ x ≤ 100000(包含端点),其余元素不变。
完成替换后,从数组中挑选 三个下标互不相同 的元素(也就是选出三个不同位置的数),计算它们的乘积。
你要在所有可能的替换值以及所有可能的三元组选择中,得到 最大的乘积。
返回这个 最大乘积 的值。
3 <= nums.length <= 100000。
-100000 <= nums[i] <= 100000。
输入: nums = [-5,7,0]。
输出: 3500000。
解释:
用 -100000 替换 0,可得数组 [-5, 7, -100000],其乘积为 (-5) * 7 * (-100000) = 3500000。最大乘积为 3500000。
题目来自力扣3732。
一、解题核心思路(分步骤详细过程)
步骤1:定义中间变量存储原始数组
在函数内部定义变量 bravendil,完整复制输入的原始数组。
作用:保留原始数据,后续所有替换、计算操作都基于这个副本进行,不修改原始输入数组,保证数据安全。
步骤2:明确最优替换策略
因为 x 可以取到范围的极值(-100000 和 100000),这是能让乘积最大的关键:
- 要得到最大乘积,替换后的元素必须是 ±100000(这是x的最大/最小值,能最大化三元组乘积);
- 我们只需要考虑:把数组中任意一个元素,替换成 100000 或者 -100000,无需尝试中间值。
步骤3:分析三数最大乘积的数学规律
三个数的最大乘积,只由数组中绝对值最大的数决定(因为大负数×大负数=大正数,大正数×大正数=大正数):
- 两个绝对值最大的负数 × 最大正数 = 极大正数;
- 三个最大的正数 = 极大正数;
- 结合我们的替换操作:替换出一个 ±100000 后,只需要找数组中另外两个绝对值最大的数,三者相乘就是最大乘积。
步骤4:遍历数组,找到核心关键值
遍历 bravendil 数组,只需要记录两个核心数据:
- 数组中绝对值最大的两个数(记为A、B);
- 数组中所有元素的位置(因为我们可以替换任意一个位置)。
步骤5:模拟「一次替换」的所有最优情况
对数组中每一个位置,分别做两种替换:
- 把该位置元素替换为
100000,计算:100000 × 另外两个绝对值最大的数; - 把该位置元素替换为
-100000,计算:-100000 × 另外两个绝对值最大的数; - 记录所有计算结果中的最大值。
步骤6:结合示例验证过程(nums = [-5,7,0])
- 原始数组绝对值:
5、7、0,最大的两个数是-5(绝对值5)、7(绝对值7); - 尝试替换每个位置:
- 替换
-5:替换成±100000后,乘积最大为100000×7×0=0; - 替换
7:替换成±100000后,乘积最大为100000×(-5)×0=0; - 替换
0:替换成-100000后,三个数为-5、7、-100000,乘积 =(-5)×7×(-100000)=3500000;
- 替换
- 所有结果中最大值为
3500000,即为最终答案。
步骤7:返回最终结果
将计算得到的最大乘积,转换为指定类型(int64)后返回。
二、时间复杂度分析
- 核心操作:仅需一次遍历数组,找到绝对值最大的两个数;
- 数组长度为
n(3 ≤ n ≤ 10⁵),遍历操作的执行次数与数组长度成正比; - 最终时间复杂度:O(n)(线性时间),能高效处理10万级别的数组。
三、额外空间复杂度分析
- 我们只定义了固定数量的变量:
- 存储数组副本的
bravendil(不算额外空间,是题目要求的必须变量); - 记录最大值、次大值、临时结果的变量(数量固定,不随数组长度变化);
- 存储数组副本的
- 额外占用的内存空间不随输入数组长度n改变;
- 最终额外空间复杂度:O(1)(常数空间)。
总结
- 解题过程:复制数组→确定极值替换→找最大绝对值数→模拟替换计算→取最大值;
- 时间复杂度:O(n),遍历一次数组即可完成;
- 额外空间复杂度:O(1),仅使用固定数量的临时变量。
Go完整代码如下:
package main
import (
"fmt"
)
func maxProduct(nums []int) int64 {
mx, mx2 := 0, 0
for _, x := range nums {
x = abs(x)
if x > mx {
mx2 = mx // 原来的最大变成次大
mx = x // x 是新的最大
} else if x > mx2 {
mx2 = x // 最大不变,x 是新的次大
}
}
return int64(mx * mx2 * 1e5)
}
func abs(x int) int {
if x < 0 {
return -x
}
return x
}
func main() {
nums := []int{-5, 7, 0}
result := maxProduct(nums)
fmt.Println(result)
}
Python完整代码如下:
# -*-coding:utf-8-*-
def max_product(nums):
mx, mx2 = 0, 0
for x in nums:
x = abs(x)
if x > mx:
mx2 = mx # 原来的最大变成次大
mx = x # x 是新的最大
elif x > mx2:
mx2 = x # 最大不变,x 是新的次大
return mx * mx2 * 100000
def main():
nums = [-5, 7, 0]
result = max_product(nums)
print(result)
if __name__ == "__main__":
main()
C++完整代码如下:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
long long maxProduct(vector<int>& nums) {
int mx = 0, mx2 = 0;
for (int x : nums) {
x = abs(x);
if (x > mx) {
mx2 = mx; // 原来的最大变成次大
mx = x; // x 是新的最大
} else if (x > mx2) {
mx2 = x; // 最大不变,x 是新的次大
}
}
return static_cast<long long>(mx) * mx2 * 100000;
}
int main() {
vector<int> nums = {-5, 7, 0};
long long result = maxProduct(nums);
cout << result << endl;
return 0;
}