NC106 三个数的最大乘积
描述: 给定一个长度为 nn 的无序数组 AA ,包含正数、负数和 0 ,请从中找出 3 个数,使得乘积最大,返回这个乘积。
要求时间复杂度: O(n) ,空间复杂度: O(1) 。
数据范围:3≤n≤10^4,-10^4≤A[i]≤10^4
思路:数组的情况分为全正数,全负数,正数+负数,正数+0,0+负数,正数+0+负数。如果数组长度为3,直接全部相乘,
全正数:最大的3个数相乘(3大)。
全负数:3大。
正数+负数:可能是一正n(n>=3)负,两正n(n>=2)负,三正n(n>=1)负。
- 一正的情况,结果为一正两负相乘(1大2小)。
- 两正的情况,情况同一正。
- 三正n(n>=1)负,结果为三正(3大)或一正两负(1大2小)
正数+0:3大
负数+0:3大
正数+0+负数:
- 一正:若只有一个负数,则一正数、N个0、一负数,则结果为0,3大相乘为0,1大2小相乘也为0。若负数个数>=2,则结果为一正两负(1大2小)
- 两正:情况同一正
- 三正:结果为三正(3大)或一正两负(1大2小)
总结:最后的结果要么是3大,要么是(1大2小),所以只需要遍历一遍,找出3大和1大2小,然后比较3大乘积和1大2小的乘积(其中都有最大值,所以比较第2大*第3大与最小的两个数的乘积),谁更大就返回谁。
方法不难,就是梳理各种情况,弄得我头疼,我之前老纠结0的问题,代码的if写了一堆,之前还把数组分成正负,正数取最大的三个值,负数取最大的3个值和最小的2个值,后来发现,其实情况就两种,需要的值并没有那么多。可以直接用两个数组存数据,一个存最大的三个值,一个存最小的两个值,然后乘积比较。我这写得还复杂一点。
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 最大乘积
# @param A int整型一维数组
# @return long长整型
#
class Solution:
def solve(self , A: List[int]) -> int:
# write code here
arr = {'max1':0,'max2':0,'max3':0,'min1':0,'min2':0}
if len(A) == 3:
return A[0]*A[1]*A[2]
for i in A:
if (arr['max1'] == 0) | (i > arr['max1']):
arr['max3'] = arr['max2']
arr['max2'] = arr['max1']
arr['max1'] = i
elif (arr['max2'] == 0) | (i > arr['max2']):
arr['max3'] = arr['max2']
arr['max2'] = i
elif (arr['max3'] == 0) | (i > arr['max3']):
arr['max3'] = i
if (arr['min1'] == 0) | (i < arr['min1']):
arr['min2'] = arr['min1']
arr['min1'] = i
elif (arr['min2'] == 0) | (i < arr['min2']):
arr['min2'] = i
if arr['max2'] * arr['max3'] < arr['min1'] * arr['min2']:
return arr['max1'] * arr['min1'] * arr['min2']
else:
return arr['max1'] * arr['max2'] * arr['max3']