剑指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} \]

算法流程:

  1. 初始化:数组 \(B\) ,大小为 \(n\),元素初始值为 \(1\) ;辅助变量 \(tmp = 1\)
  2. 计算 \(B[i]\) 的 下三角 各元素的乘积,直接乘入 \(B[i]\)
  3. 计算 \(B[i]\) 的 上三角 各元素的乘积,记为 \(tmp\) ,并乘入 \(B[i]\)
  4. 返回 \(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;
    }
};
posted @ 2021-02-18 16:09  RiverCold  阅读(28)  评论(0编辑  收藏  举报