一个程度为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反向扫描的结果。
本文介绍了一种在数组更新问题中,不使用除法实现线性时间复杂度算法的方法。通过利用两个辅助空间,分别存储从数组开头到当前元素的连续乘积和从当前元素到结尾的连续乘积,从而达到更新数组元素的目的。
600

被折叠的 条评论
为什么被折叠?



