剑指offer51_构建乘积数组_题解
构建乘积数组
题目描述
给定一个数组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]\) 递推公式为:
\[B[n]=B[n-1]*A[i-1]\tag{1<=i<=n-1}
\]
当只看上三角元素时,上三角元素 \(B[i]\) 递推公式为:
\[B[n]=B[n+1]*A[i+1]\tag{0<=i<=n-2}
\]
算法流程:
- 初始化:数组 \(B\) ,大小为 \(n\),元素初始值为 \(1\) ;辅助变量 \(tmp = 1\) ;
- 计算 \(B[i]\) 的 下三角 各元素的乘积,直接乘入 \(B[i]\) ;
- 计算 \(B[i]\) 的 上三角 各元素的乘积,记为 \(tmp\) ,并乘入 \(B[i]\) ;
- 返回 \(B\) 。
代码
/**
1.时间复杂度:O(n)
2.空间复杂度:O(1)
**/
class Solution
{
public:
vector<int> multiply(const vector<int> &A)
{
int n = A.size();
vector<int> B(n, 1);
for(int i = 1; i <= n - 1; i++){
B[i] = B[i - 1] * A[i - 1];
}
int tmp = 1;
for(int i = n - 2; i >= 0; i--){
tmp *= A[i + 1];
B[i] *= tmp;
}
return B;
}
};