238. Product of Array Except Self (Medium)
Given an array
nums
of n integers where n > 1, return an arrayoutput
such thatoutput[i]
is equal to the product of all the elements ofnums
exceptnums[i]
.Example:
Input:[1,2,3,4]
Output:[24,12,8,6]
Note: Please solve it without division and in O(n).
Follow up:
Could you solve it with constant space complexity? (The output array does not count as extra space for the purpose of space complexity analysis.)
1 space O(1),time O(n), 但使用了division ,先计算了所有不是0的乘积
这道题的corner case主要考虑0,1个0和多个0,
如果有多个0,那乘积就算排除自己也是0,
如果只有1个0,那如果自己是0,乘积就不是0
如果没有0,就要除自己
class Solution:
def productExceptSelf(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
product = []
if not nums:return []
allpro = 1
zeronum = 0
for i in nums:
if i==0:zeronum+=1
else:allpro *= i
for i in range(len(nums)):
if zeronum > 1:product.append(0)
elif zeronum == 1 and nums[i]!=0:product.append(0)
elif zeronum == 1 and nums[i]==0:
product.append(allpro)
else:#no zero
product.append(int(allpro/nums[i]))
return product
1 space O(1),time O(n), 不使用division: two pointers
返回一个新list:prod
prod[i] = nums[0] * nums[1] *...*nums[i - 1] * nums[i+1]*...*nums[len-1]
= 该数左边乘积 * 该数右边乘积
| 0 |1 | 2|...| i - 1| i | i+1| ...| len-1|
left ——> | <——right
<——right | left ——>
right left
使用left和right指针 ,left从左往右扫描 ,right从右往左扫描
left扫描到的位置计算前面的乘积并记录到prod里 ; right扫描到的位置计算后面的乘积记录到prod里
这样的话刚开始两个都是各自计算无交集,等到left和right走到一半并各自继续扫描时,
这时候prod右半边是已经计算过右乘积的,prod左半边是已经计算过左乘积的,
left往右半边继续走,并把左乘积乘上prod[i] (<--这个prod[i]已经是右边乘积),得到左乘积*右乘积,同理right
知道left和right各自走到底,此时左右乘积均计算完毕。
注意 pord初始化为1,长度与nums同,因为prod[0] 没有左乘积,prod[len-1]没有右乘积,所以初始化为1 ,prod[0]乘以右乘积和prod[len-1]乘以左乘积时才会不变
class Solution:
def productExceptSelf(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
prod = [1]*len(nums)
left = 0;right = len(nums)-1
prodleft , prodright = nums[left],nums[right]
while(left < len(nums)-1):
prod[left + 1] *= prodleft
prod[right - 1] *= prodright
prodleft *= nums[left+1]
prodright *= nums[right-1]
left += 1
right -= 1
return prod
更直观一点是扫描2边,一次left扫描到右边,一次right扫描到左边,
prod = [1]*len(nums)
left = 0
prodleft = nums[left]
while(left < len(nums)-1):
prod[left+1] *= prodleft
prodleft *= nums[left+1]
left += 1
right = len(nums)-1
prodright = nums[right]
while(right >0):
prod[right - 1] *= prodright
prodright *= nums[right -1]
right -= 1
return prod