一、前言
让人成长的不是岁月,而是经历。
每天五分钟,看懂一道简单、中等难度的算法题,尽可能将复杂的题讲清楚。
疯狂学习python中,2020-06-02更新
二、题目
给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。
示例:
输入: [1,2,3,4]
输出: [24,12,8,6]
**提示:**题目数据保证数组之中任意元素的全部前缀元素和后缀(甚至是整个数组)的乘积都在 32 位整数范围内。
说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。
进阶:
你可以在常数空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/product-of-array-except-self
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
三、解题思路
3.1 步骤解释
输入: [1,2,3,4]
输出: [24,12,8,6]
24 = 1 * 2 * 3 * 4
12= 1 * 2 * 3 * 4
8= 1 * 2 * 3 * 4
6= 1 * 2 * 3 * 4
如果抛开不能使用除法这个限制条件,那么这个题是一个简单题,通过列表求乘积,然后除以自身的值即可。
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
l = []
for i in nums:
l.append(reduce(lambda x, y: x*y, nums)/i)
print(l)
但是如果列表中有为0的元素,则会报错。
3.1 左右乘积法
思路:
- 遍历记录每个位置之前前缀的乘积和每个位置之后后缀的乘积。
- 遍历记录每个位置前缀乘积乘以后缀乘积返回。
对于进阶所提到的在常数空间复杂度内完成题目,可以直接将答案存储在输出数组中。即首先循环数组,得到图中的leftProduct数组,只不过此时是使用res数组来存的。
接下来简单化简一下计算流程:
res[i] = L[i] * R[i]
由于:L[i]此时存储在res[i]中的
因此:res[i] = res[i] * R[i]
由于:R[i] = nums[i + 1] * R[i + 1]
因此:res[i] = res[i] = (nums[i + 1] R[i + 1])**
参考来源:图解LeetCode238. 除自身以外数组的乘积
四、代码实例
4.1 左右乘积法
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
length = len(nums)
res = [1] * length # 初始化长度为 le(nums) 的数组
R, L = 1, 1 # 左右的乘积
# 右边的乘积
for i in (reversed(range(length))):
R *= nums[i]
res[i] = R
# 左边乘积*右边的乘积
for i in range(length - 1):
res[i] = res[i + 1] * L
L *= nums[i]
res[-1] = L
return res