[算法] 子数组的最大乘积
《编程之美》2.13 子数组的最大乘积
题目: 给定一个长度为N的整数数组, 只允许用乘法, 不能用除法, 计算任意(N-1)个数的组合乘积中最大的一组, 并写出算法的时间复杂度.
一开始想到的就是给的第二种解法. 有谁会一开始就去算乘积吗?
- 数组中有多于一个零则最大乘积为0
- 数组中只有一个零, 而有奇数个负数, 则最大乘积必定为0
- 数组中只有一个零, 而有偶数个负数, 则最大乘积为除去0的元素的乘积
- 数组中没有零, 而有奇数个负数, 则最大乘积为除去绝对值最小的负数的乘积
- 数组中没有零, 而有偶数个负数, 则最大乘积为除去最小的正数的乘积
时间复杂度: O(n)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def find_max_multiply(A):
negative_c = zero_c = n_min = 0
p_min = float('inf')
for i in range(len(A)):
if A[i] == 0:
if zero_c == 1: return 0 # 多于一个零则最大乘积为0
zero_c += 1
zero_index = i
elif A[i] < 0:
negative_c += 1
if A[i] < n_min:
n_min = A[i]
n_index = i
elif A[i] < p_min:
p_min = A[i]
p_index = i
if zero_c == 1: # 数组中只有一个零
if negative_c % 2 == 0: # 偶数个负数
exclude_index = zero_index
else: # 奇数个负数
return 0
else: # 数组中没有零
if negative_c % 2 == 0: # 偶数个负数
exclude_index = p_index
else: # 奇数个负数
exclude_index = n_index
result = 1
for i in range(0, len(A)):
if i == exclude_index:
continue
result *= A[i]
return result
if __name__ == "__main__":
A = [[1, 2, 3, 4, 5, 0, 0], # 数组中有多于一个零则最大乘积为0
[1, 2, 3, -4, -5, -6, 0], # 数组中只有一个零, 而有奇数个负数, 则最大乘积必定为0
[1, 2, 3, 4, 5, 6, 0], # 数组中只有一个零, 而有偶数个负数, 则最大乘积为除去0的元素的乘积
[1, 2, 3, 4, 5, 6, 7], # 数组中没有零, 而有偶数个负数, 则最大乘积为除去最小的正数的乘积
[1, 2, 3, 4, 5, -6, -7], # 数组中没有零, 而有偶数个负数, 则最大乘积为除去最小的正数的乘积
[1, 2, 3, 4, 5, 6, -7]] # 数组中没有零, 而有奇数个负数, 则最大乘积为除去绝对值最小的负数的乘积
print([find_max_multiply(a) for a in A])