leetcode 152
在整数的列表中寻找一个乘积最大的子列, 输出该乘积. 子列指连续的一个区间.
整数有0, 负数和正数. 在非零的情况下, 乘积的绝对值是会随着数组长度的增长而增加的.
首先找到所有的0, 将数组分割为若干个只包含0长度为1的子列和若干个不包含0的子列.
现在求解一个不含0的数组的连续乘积最大值, 如果包含的负数为偶数个, 则是所有数的乘积. 如果包含负数为奇数个, 则最后一个负数之前的数的乘积或者是第一个负数之后的数的乘积.
计算复杂度为O(n), 空间复杂度可以到O(1), 但是我暂时写了一个为O(n)的版本, 也通过了.
class Solution:
def maxProductWithoutZero(self, nums: List[int], start_index, end_index) -> int:
if start_index == end_index:
return nums[start_index]
minus_index_list = []
for i in range(start_index, end_index + 1):
v = nums[i]
if v < 0:
minus_index_list.append(i)
if len(minus_index_list) % 2 == 1:
tmp_1 = 1
for i in range(minus_index_list[0] + 1, end_index + 1):
tmp_1 *= nums[i]
tmp_2 = 1
for i in range(start_index, minus_index_list[-1]):
tmp_2 *= nums[i]
return max(tmp_1, tmp_2)
else:
result = 1
for i in range(start_index, end_index + 1):
result *= nums[i]
return result
def maxProduct(self, nums: List[int]) -> int:
if not nums:
return None
zero_index_list = [-1]
for i, v in enumerate(nums):
if v == 0:
zero_index_list.append(i)
result = nums[0]
zero_index_list.append(len(nums))
for i in range(len(zero_index_list)-1):
if zero_index_list[i] + 1 <= zero_index_list[i+1] - 1:
tmp_result = self.maxProductWithoutZero(nums, zero_index_list[i] + 1, zero_index_list[i+1] - 1)
if tmp_result > result:
result = tmp_result
if len(zero_index_list) > 2:
if 0 > result:
result = 0
return result