数组连乘问题

一个程度为N的数组,现在要令

a[0] = a[1]*a[2]....a[n-1]

a[1] = a[0]*a[2]....a[n-1]

a[2] = a[0]*a[1]....a[n-1]

...

a[n-1] = a[0]*a[2]...a[n-2]

 

条件是不能用除法,时间复杂度必须是线性。

 

观察一下题目,每一个元素 i 都被更新成了a[0]到a[n-1],除去 i 下标元素外的所有其它元素的连乘。

这题如果能用除法,则可以用以下的办法来搞定:

1. 计算a[0]到a[n-1]的乘积M。

2. 用乘积M除以各个元素就是相应下标的解。

 

但是,搜狗说你们这么搞显得我们没有技术含量,于是不允许用除法。

在这样的前提下,我们观察一下题目。不难得到这样的结论:

 

每一个下标i的乘积被分割成了两部分

第一部分:从a[0]到a[i-1]的连乘

第二部分:从a[i+1]到a[n-1]的连乘

 

于是我们使用两个同样n元素的辅助空间来解决问题。

第一个辅助空间B用来存放第一部分的乘积。

 

1;a[0];a[0]a[1];...;a[0]a[1]...a[n-2];

 

第二个辅助空间C存放第二部分的乘积

 

a[1]a[2]...a[n-1];a[2]...a[n-1];a[3]...a[n-1];...;1;

 

 

最后结果a[i] = B[i]*C[i]

那么,明显,B的形成是数组a正向扫描的结果,C的形成是a反向扫描的结果。

 

[cpp] view plaincopyprint?

  1. int nRes = 1;  
  2. B[0] = 1;  
  3. C[n-1] = 1;  
  4.   
  5. for(int i=1;i<n;i++)  
  6. B[i] = (nRes *= a[i-1]);  
  7.   
  8. nRes = 1;  
  9.    
  10. for(int i=n-2;i>0;i--)  
  11. C[i] = (nRes *= a[i+1]);  
  12.   
  13. for(int i=0;i<n;i++)  
  14. a[i] = B[i]*C[i];  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值