您的位置:首页 > 其它

腾讯2013的一道实习生笔试题

2017-03-02 20:47 204 查看

腾讯2013的一道实习生笔试题

题目

给定一个数组a
,我们希望构造数组b
,其中b[i]=a[0]*a[1]*...*a[N-1]/a[i]。
在构造过程:不允许使用除法;
要求:O(1)空间复杂度和O(n)时间复杂度;
除遍历计数器与a
b
外,不可使用新的变量(包括栈临时变量、对空间和全局静态变量等);
请用程序实现并简单描述。


题目解析

本身这个题是很容易实现的,但是加了诸多限制,就比较有意思了。
我们一个一个来分析
1.不能使用除法,这个好解决,只要乘的过程中不乘a[i]即可,那么整个a数组就被分成了两部分,
一个是i位置前,一个是i位置后,注意:这个思考很关键,后面的实现都是基于它的,也可以说是
用了一点点分治吧

2.O(1)空间复杂度,没什么说的。

3.O(n)时间复杂度,就是说只能一重循环,注意:只能用一重循环,
但是没说用几次一重循环,也就是说可以多次,一次一重循环谁也做不出来。

4.除遍历计数器与a
b
外,不可使用新的变量(包括栈临时变量、对空间和全局静态变量等),
这个就厉害了,不能用变量存储值,就只能存在数组中,不能用栈临时变量,也就是不能用递归了,
没有这个条件的话用递归和一重循环也不是很难就可以做到。


逻辑思维好的可以直接看代码

分析过程

这个题目我们主要是运用迭代的思想,不断更新数据,首先前面我们说了a数组被分成两部分,前一部分和后一部分;

首先解决前一部分,当然是用b数组来存储结果,
b[1] = a[0]
b[2] = a[0]a[1]
…
b[i] = a[0]a[1]a[2]…a[i-1]
通过演算我们发现b[i]都要比a[i]多一个a[i-1],那么可以写成b[i] = b[i-1] + a[i-1],至于b[0],
就赋值1就好啦,这样我们就把前半部分解决了。这就是迭代的思想

后半部分还是得用迭代的思想,我们用b[0]来存后半部分,并迭代更新,只要逆序就好了,
看代码更直观,有了前面的铺垫相信很快就能看懂


/*
以三个元素举例
*/
#include <stdio.h>
#define N 3
int a
= {5,4,3};
int b
;
void Translate(int a[], int b[],int n)
{
b[0] =  1;
for(int i = 1; i < n; i++)
{
b[i] = b[i-1] * a[i-1];     //b[i]保存的是a[0]一直到a[i-1]的乘积,也就是a在i位置之前所有元素的乘积
}
for(int i = n-1; i > 0; i--)
{
b[i] *= b[0];       //b[0]存储的是a[i+1]到a
的乘积,也就是a在i位置之后所有元素的乘积
b[0] *= a[i];       //b[0]的值迭代更新
}
}
int main()
{
int i;
Translate(a,b,N);
for(i = 0; i < N; i++)
printf("%d ",b[i]);
return 0;
}


参考此博客作出,上面还有两种方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: