题⽬描述
给定⼀个数组A[0,1,…,n-1] ,请构建⼀个数组B[0,1,…,n-1],其中B 中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1] 。不能使⽤除法。(注意:规定B[0] =A[1] * A[2] * ... * A[n-1],B[n-1] = A[0] * A[1] * ... * A[n-2] )
对于A ⻓度为1 的情况,B⽆意义,故⽽⽆法构建,因此该情况不会存在。
输⼊:[1,2,3,4,5] 输出:[120,60,40,30,24]
思路及解答
暴力
对每个B[i]都计算A中除A[i]外所有元素的乘积,双重循环,外层遍历B的每个位置,内层遍历A数组跳过当前元素
时间复杂度:O(n²),需要嵌套循环遍历数组
空间复杂度:O(1),除结果数组外只使用常数空间
左右乘积数组法(空间换时间)
使用左右两个辅助数组存储乘积信息
思路:left[i]表示A[0]到A[i-1]的乘积,right[i]表示A[i+1]到A[n-1]的乘积
时间复杂度:O(n),三次单层循环
空间复杂度:O(n),需要两个辅助数组
矩阵视角理解: 如果把问题看作矩阵,B[i]就是去掉对角线元素A[i]后,该行所有元素的乘积。
左右分解策略:
left[i]= A[0] × A[1] × … × A[i-1] (i左边的乘积)right[i]= A[i+1] × A[i+2] × … × A[n-1] (i右边的乘积)B[i] = left[i] × right[i](左右乘积相乘正好去掉A[i])
空间优化(推荐)
在方法二的基础上优化空间使用,在结果数组B上直接进行左右乘积计算。
先用B数组存储左侧乘积,再用变量动态计算右侧乘积
时间复杂度:O(n),两次遍历数组
空间复杂度:O(1),除结果数组外只使用常数空间
算法步骤详解
第一步:左侧乘积计算
第二步:右侧乘积整合