152. Maximum Product Subarray
Given an integer array nums, find the contiguous subarray within an array (containing at least one number) which has the largest product.
Example 1:
Input: [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product = 6.
Example 2:
Input: [-2,0,-1]
Output: 0
Explanation: The result cannot be 2, because [-2,-1] is not a subarray.
解题思路:
分析题目,先假设数组中没有0元素,若数组所有元素累乘的结果是正数,则该数组自身就是拥
有最大乘积的子数组。否则,数组中存在奇数个负数,且显然一个数组的乘积的绝对值必然大于子
数组的乘积,所以一个数组的最大子数组乘积至多只需要从该数组中剔除一个负数,因此只需从数
组两头开始往中间遍历,各找到离数组头最近的负数i与离数组尾最近的负数j,如果i与j是同一
个数,则以该负数为界划分得到的两个子数组中乘积较大的一个就是答案;否则比较从头到i与从
尾到j的乘积,剔除绝对值较小者,剩余的子数组就是答案。
而考虑数组中有0的情况,只需以0为界划分不含0的数组,求得到的所有子数组的最大乘积中的
最大者即可。
代码展示:
def multi(numsl):
"""返回列表中所有元素的值进行累乘的结果"""
# if the number list is not empty
if numsl :
result = numsl[0]
for i in range(1,len(numsl)):
result *= numsl[i]
return result
else:
return 0
def max_pr_withoutzero(nums):
"""计算没有0的数组中拥有最大乘积的子数组的乘积"""
if not nums:
return 0
if multi(nums) > 0:
return multi(nums)
head, tail = 0, len(nums) - 1
while nums[head] > 0 and head < len(nums) - 1:
head += 1
while nums[tail] > 0:
tail -= 1
if tail == head:
if multi(nums[:head]) > multi(nums[tail + 1:]):
return multi(nums[:head])
else:
return multi(nums[tail + 1:])
else:
if multi(nums[:head + 1]) > multi(nums[tail:]):
return multi(nums[head + 1:])
else:
return multi(nums[:tail])
class Solution:
def maxProduct(self, nums):
"""
:type nums: List[int]
:rtype: int
计算给定数组的子数组的最大乘积
"""
if len(nums) == 1:
return nums[0]
if multi(nums) != 0:
return max_pr_withoutzero(nums)
else:
head, tail = 0, 0
max_product = 0
while tail != len(nums):
while tail < len(nums) - 1 and nums[tail] != 0:
tail += 1
# if tail points to the last element of the list, let it points to the tail of whole list
if tail == len(nums) - 1 and nums[tail] != 0:
tail += 1
temp = max_pr_withoutzero(nums[head:tail])
if max_product < temp:
max_product = temp
head = tail + 1
if tail != len(nums):
tail += 1
return max_product