給定一個無序數組,包含正數、負數和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; } }