628. 三个数的最大乘积
难度简单
题目描述
给你一个整型数组 nums。
在数组中找出由三个数组成的 最大 乘积,并返回这个 最大 乘积。
示例 1:
输入:nums = [1,2,-3] 输出:-6 解释:只有三个数字 1、2 和 -3,因此最大乘积是 1 * 2 * -3 = -6。
示例 2:
输入:nums = [1,2,3,4] 输出:24 解释:最大的乘积来自三个最大的数字:2 * 3 * 4 = 24。
示例 3:
输入:nums = [-1,-2,-3] 输出:-6 解释:只有三个数字 -1、-2 和 -3,因此最大乘积是 (-1) * (-2) * (-3) = -6。
提示:
3 <= nums.length <= 104-1000 <= nums[i] <= 1000
解法
方法一:排序 + 分类讨论
思考
三个数乘积的最大者,可能来自三个最大正数,也可能来自两个绝对值很大的负数再乘最大正数。 \(n\le 10^4\),排序后分类即可。
排序后比较 \(nums[-1]\times nums[-2]\times nums[-3]\) 与 \(nums[-1]\times nums[0]\times nums[1]\),覆盖全正、全负与正负并存。
我们先对数组 \(\textit{nums}\) 进行排序,接下来分两种情况讨论:
- 如果 \(\textit{nums}\) 中全是非负数或者全是非正数,那么答案即为最后三个数的乘积,即 \(\textit{nums}[n-1] \times \textit{nums}[n-2] \times \textit{nums}[n-3]\);
- 如果 \(\textit{nums}\) 中既有正数也有负数,那么答案可能是两个最小负数和一个最大整数的乘积,即 \(\textit{nums}[n-1] \times \textit{nums}[0] \times \textit{nums}[1]\);也可能是最后三个数的乘积,即 \(\textit{nums}[n-1] \times \textit{nums}[n-2] \times \textit{nums}[n-3]\)。
最后返回两种情况的最大值即可。
时间复杂度 \(O(n \times \log n)\),空间复杂度 \(O(\log n)\)。其中 \(n\) 为数组 \(\textit{nums}\) 的长度。
1 2 3 4 5 6 | |
1 2 3 4 5 6 7 8 9 | |
1 2 3 4 5 6 7 8 9 10 | |
1 2 3 4 5 6 7 8 9 10 | |
1 2 3 4 5 6 7 | |
方法二:一次遍历
思考
方法一付出排序的 \(O(n\log n)\)。乘积只依赖最小两个与最大三个数,一次遍历(或 nlargest)维护这五个极值即可降到线性。
我们可以不用对数组进行排序,而是维护五个变量,其中 \(\textit{mi1}\) 和 \(\textit{mi2}\) 表示数组中最小的两个数,而 \(\textit{mx1}\), \(\textit{mx2}\) 和 \(\textit{mx3}\) 表示数组中最大的三个数。
最后返回 \(\max(\textit{mi1} \times \textit{mi2} \times \textit{mx1}, \textit{mx1} \times \textit{mx2} \times \textit{mx3})\) 即可。
时间复杂度 \(O(n)\),其中 \(n\) 为数组长度。空间复杂度 \(O(1)\)。
1 2 3 4 5 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |