给定一个无序数组,包含正数、负数和0,要求从中找出3个数的乘积,使得乘积最大,要求时间复杂度:O(n),空间复杂度:O(1)
输入描述:
无序整数数组A[n]
输出描述:
满足条件的最大乘积
输入例子1:
3 4 1 2
输出例子1:
24
求三个数字的最大乘积。
1. 数组全部是正数,最大三个数的乘积
2. 数组全部是负数,最大三个数的乘积
3. 数组有正有负,最大的一个数和最小的两个数的乘积
所以一共需要计算五个值:数组中最大的三个值和最小的两个值
比较最大三个数的乘积和最大一个数与最小两个数的乘积。
因为题目要求时间复杂度为O(1),故不能先排序。
所以需要在遍历的同时找出这五个数。
参考代码如下:
#include <iostream> #include <vector> #include <climits> #include <cmath> using namespace std; int main() { int n; while (cin >> n) { vector<long long> nums(n, 0); // 读取输入 for (int i = 0; i < n; ++i) { cin >> nums[i]; } // 定义需要计算的数值 long long max1 = 0, max2 = 0, max3 = 0, min1 = 0, min2 = 0, res1 = 0, res2 = 0; // 比较数组前三个数找出其中的大小关系来确定五个数 max1 = max(nums[0], nums[1]); max2 = min(nums[0], nums[1]); if (nums[2] > max1) { max3 = max2; max2 = max1; max1 = nums[2]; } else if (nums[2] > max2) { max3 = max2; max2 = nums[2]; } else max3 = nums[2]; min1 = max3; min2 = max2; // 根据前面确定的关系遍历数组。更新五个目标值 for (int i = 3; i < n; ++i) { if (nums[i] < min1) { min2 = min1; min1 = nums[i]; } else if (nums[i] < min2) { min2 = nums[i]; } if (nums[i] > max1) { max3 = max2; max2 = max1; max1 = nums[i]; } else if (nums[i] > max2) { max3 = max2; max2 = nums[i]; } else if (nums[i] > max3) max3 = nums[i]; } // 计算三个最大数的乘积 res1 = max1 * max2 * max3; // 计算一个最大数和两个最小数的乘积 res2 = max1 * min1 * min2; // 输出结果 cout << max(res1, res2) << endl; return 0; } }