【腾讯2012年实习生笔试加分题】不使用除法,由给定数组a[N]构造数组b [N],其中b[j]=a[0]*a[1]*…*a[N-1] / a[j]

【题目描述】
给定一数组a[N],我们希望构造数组b [N],其中b[j]=a[0]*a[1]*…*a[N-1] / a[j]。

三点要求如下:
在构造过程中,不允许使用除法;
O(1)空间复杂度和O(n)的时间复杂度;
除遍历计数器与a[N] b[N]外,不可使用新的变量(包括栈临时变量、堆空间和全局静态变量等);

实现程序(主流编程语言任选)并简单描述。

【感悟】
一开始看到题目时,并没有想法,因为不允许除法而且所要求的每个乘积并不连续,那么按我的方法就要O(n^2)的复杂度。
后来索性扫了一眼答案,就扫了一眼,我看到了b[i]=b[i-1]*…,突然一下子茅塞顿开,后来我就自己想出来了。
他是先用数组来存储一部分的乘积项,而不是一次性的就变成了结果。而我之前没意识到其实所需结果的每个乘积都可以以其自身往左右切割为两部分的连续积!以abcdefg为例结果即:
1 bcdefg
a cdefg
ab defg
abc efg
abcd fg
abcde g
abcdef 1
从上可见,每个部分都是递进相乘的!这就好办了,假如我们不考虑变量,那么用两个外部变量来循环存这两系列值即可。
但现在要求不用迭代器i之外的变量,那么我们发现第二系列的值,从下往上随着乘法进行,最后这个临时值就是b[0]的结果,故可用b[0]来替代外部变量。

【注意】关于算法题写程序时有两件事情要细心:
1. 一个循环的初始条件,终止条件,或者迭代器的初值与末值。
2. 相关联的数据项之间的序号对应关系,弄清楚在条件1下渐变量是先作用还是后作用于目标值。

#include <stdio.h>

void trans(int *a,int *b,int n)
{
	int i;
	b[0]=1;
	for(i=1;i<n;i++)
		b[i]=b[i-1]*a[i-1];
	for(i=n-1;i>0;i--)
	{
		b[i]*=b[0];
		b[0]*=a[i];
	}
}

void main()
{
	int a[9]={1,2,3,4,5,6,7,8,9};
	int b[9];
	trans(a,b,9);
	for (int i=0;i<9;i++)
		printf("%d ",a[i]);
	printf("\n");
	for (i=0;i<9;i++)
		printf("%d ",b[i]);
	printf("\n");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值