描述
给定一个数组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无意义,故而无法构建,因此该情况不会存在。
就是B数组中的元素 i 都是A所有元素的乘积除以 i。但是不能使用除法。
①官方题解:表格分区,双向遍历
B[0]= | 1 | A[1] | A[2] | … | A[n-2] | A[n-1] |
B[1]= | A[0] | 1 | A[2] | … | A[n-2] | A[n-1] |
B[2]= | A[0] | A[1] | 1 | … | A[n-2] | A[n-1] |
… | … | … | … | … | … | … |
B[n-2]= | A[0] | A[1] | A[2] | … | 1 | A[n-1] |
B[n-1]= | A[0] | A[1] | A[2] | … | A[n-2] | 1 |
按照题目意思,就是A数组和B数组索引相同的那里换成1,所以B[i]的值就等于每一行的累乘。
- 初始化数组B。
- 先计算该矩阵的左下角部分,也就是B的左边部分。
可以看到B[i+1]_left=B[i]_left * A[i-1]
- 再计算该矩阵的右上角部分,也就是B的右边部分。
可以看到除了本身 i 以外,B[i]_right=A[i+1]*…*A[n-1]
- 所以B[i]=B_left * B_right
# -*- coding:utf-8 -*-
class Solution:
def multiply(self, A):
B, right = [1]*len(A), 1 #先定义B数组长度和右边初始值=1
#看左边的乘积
for i in range(1, len(A)): #索引起始位是从1开始的
B[i] = B[i -1] * A [i -1]
#再看右边
for i in range((len(A) -2), -1, -1): #range(start, end, step)这里表示i 从最大索引开始,每次取值减1.
right *= A[i+1] # 右边的乘积
B[i] *= right # 更新B[i] = B[左边] * B[右边]
return B
②官方题解:分别求出以自身为分界线的前面乘积,后面乘积来相乘,即是该B[i]的值。
# -*- coding:utf-8 -*-
class Solution:
def multiply(self, A):
B = [1]*len(A)
left = 1
right = 1
for i in range(len(A)):
B[i] *= left
B[len(A) - i - 1] *= right #len(A) - i - 1 表示数组B除开左边和对应自身数值后剩余的即后面的索引位置。
left *= A[i] #因为起始位是从0开始,所以left就等于A[i]的乘积。
right *= A[len(A) - i -1]
return B