实验目的:
练习贪心
实验内容:
给定一个无序数组,包含正数、负数和0,要求从中找出3个数的乘积,使得乘积最大,并且时间复杂度为O(n)、空间复杂度为O(1)。
输入描述:无序整数数组a[n]。
输出描述:满足条件的最大乘积。
输入样例:
4
3 4 1 2
样例输出:
24
思路:如果数组个数为3,直接返回三者乘积;
如果个数大于三,因为时间复杂度要求O(n),所以只能遍历一遍,记录更新最大的三个数和最小的两个数,这样空间复杂度为O(1),答案是max(最大的三个数之积,最大的数和两个最小的数之积)。注:最小的两个如果是负数,则相乘为正数,可能为最大乘积。
代码
#include <iostream>
#include <vector>
#include<algorithm>
using namespace std;
int getmax(vector<int> p) {
int a1=0,a2=0,a3=0,b1=0,b2=0;
int n = p.size();
for (int i = 0; i < n; i++) {
if (p[i] >= a1) {
a3 = a2;
a2 = a1;
a1 = p[i];
}
else if (p[i] >= a2) {
a3 = a2;
a2 = p[i];
}
else if (p[i] >= a3) {
a3 = p[i];
}
else if (p[i] <= b1) {
b2 = b1;
b1 = p[i];
}
else if (p[i] <= b2) {
b2 = p[i];
}
}
return max(a1 * a2 * a3, a1 * b1 * b2);
}
int main()
{
int n;
cin >> n;
vector<int> p(n);
int ans;
for (int i = 0; i < n; i++) {
cin >> p[i];
}
if (n == 3) ans = p[0] * p[1] * p[2];
else ans = getmax(p);
cout << ans;
}
结果截图:
总结:
一次遍历,记录更新最大的三个和最小的两个