持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情
前言
今天是苦逼的一天,周六加班。抽空来道简单的算法题,本来以为很简单,但做着做着发现是我想简单了,每次都少考虑的情况,下面来看下题目。
题目描述
给你一个整型数组 nums ,在数组中找出由三个数组成的最大乘积,并输出这个乘积。
示例 1:
输入:nums = [1,2,3] 输出:6 示例 2:
输入:nums = [1,2,3,4] 输出:24 示例 3:
输入:nums = [-1,-2,-3] 输出:-6
解题思路
如之前文章所说,看到数组题目我就会先来个排序,这次也不例外,但这题如果只有排序是不行的,因为三个数的最大乘积有很多种情况,如下:
- 如果数组都是正数,那排序后的三个数的最大乘积就是数组的最后三项
- 如果数组中既有正数又有负数,那就要分为两种情况了,第一种是当负数的个数小于两个的时候,那数组中的三个数的最大乘积还是由数组的最后三项组成;第二种情况就是当负数的个数大于两个的时候,这时候又分为两种情况(1)取数组的前两项和数组的最后一项(2)直接取数组的最后三项。这时比较(1)和(2)谁的值大返回谁就行了
- 如果数组中全是负数,那直接取数组的前三项的乘积就是答案了 代码如下:
/**
* @param {number[]} nums
* @return {number}
*/
var maximumProduct = function (nums) {
var count = countArray(nums) //获取负数的个数
var positiveNumber
positiveNumber = isPositive(nums) //判断是否有正数
let resultPositive = 1, resultNegative = 1 //记录各种情况下乘积的值
nums = nums.sort((a, b) => a - b) //数组排序
if (nums[0] >= 0) { //全是正数的情况
for (let i = nums.length - 1; i >= nums.length - 3; i--) {
resultPositive = resultPositive * nums[i]
}
return resultPositive
} else {
//有负数,又有正数的情况
if (count >= 2 && positiveNumber) {
resultNegative = nums[0] * nums[1] * nums[nums.length - 1]
resultPositive = nums[nums.length - 1] * nums[nums.length - 2] * nums[nums.length - 3]
return resultNegative > resultPositive ? resultNegative : resultPositive
} else { //全负数的情况
resultNegative = nums[nums.length - 1] * nums[nums.length - 2] * nums[nums.length - 3]
return resultNegative
}
}
};
var countArray = function (nums) {
let count = 0
nums.forEach(item => {
if (item < 0) {
count++
}
})
return count
}
var isPositive = function (arr) {
for (let i = 0; i < arr.length; i++) {
if (arr[i] >= 0) {
return true
}
}
return false
}
运行结果如下图:
优化
上述代码是我做的时候自己的思路,后边又看了一下发现由于我进行了排序,全负数和全正数的情况其实是一样的,都是排序后数组的后三项,那其实就不用分那么多种情况考虑了,可以拿到数组,然后排序,然后比较数组最后三项的积和数组第一项,第二项,最后一项的积谁大返回谁就可以了。甚至可以不用排序,因为我们只要找到这五个值就行了