锁定老帖子 主题:谷歌的一道面试题,请大家集思广益
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (2)
|
|
---|---|
作者 | 正文 |
发表时间:2011-05-25
thihy 写道 thihy 写道 其实很Easy。设原来的数列第一项是a,差值是d。现在的数列首项是b,差值是e。
分情况(这样比较容易思考): 1. a、d都是偶数。不考虑。 2. a是偶数,d是奇数。则知道偶数项(从1开始计数)都是奇数,也即现在的数列与原来的数列中,偶数项是不变的。就可以算出d了。 3. a是奇数,d是偶数。则知道所有项都是奇数,也即不变。 4. a、d是奇数,则奇数项都是奇数,也即不变。 然后求出最小的数组。 比如现在的是:1,1,3,1。按照情况2,偶数项都是奇数(1,1),故而d=0,显然不符合。 按照情况3,显然也不符合。按照情况4,d=(3-1)/2=1,故而为1,2,3,4,验证偶数项,满足。 显然,考察对象要从首项开始,只看前三个数字就可以了 刚先看贴后自己推算了下, 居然和thihy的想法相同,至于a1,d都为偶数的情况,可以归并到2,3,4的情况。 这个面试题,应该求的是最小和等差数组(范围定义在整数范围内) |
|
返回顶楼 | |
发表时间:2011-05-25
如果没有额外的限定条件的话,原数列是得不到的。
因为等差数列的每一项乘以一个同样的因子,得到的仍然是一个等差数列 如果有限定条件,比如最少有一个是奇数,则理论上应该可以。 |
|
返回顶楼 | |
发表时间:2011-05-25
ubotutwin 写道
lzyzizi 写道
Cross_Lee 写道
2234 下来也是 1131。
所以只根据这些条件是不能反向得到唯一的1234的。 注意是等差数列,同学
假设如果有算法能将一个处理后的数组还原到1、2、3、4,那怎么判断原数组是1、2、3、4还是2、4、6、8? 嗯 +1 |
|
返回顶楼 | |
发表时间:2011-05-25
fflame 写道 如果没有额外的限定条件的话,原数列是得不到的。
因为等差数列的每一项乘以一个同样的因子,得到的仍然是一个等差数列 如果有限定条件,比如最少有一个是奇数,则理论上应该可以。 又仔细考虑一下,发现之前考虑的不完全: 按题目要求: 等差数组234和等差数组432处理以后得到的结果都是: 131 于是失败 也许只有3个数的数列太短,多于3个可以?需要去讨论边界了,麻烦…… |
|
返回顶楼 | |
发表时间:2011-05-25
最后修改:2011-05-26
public class Test { public static void main(String[] args) { // 64,127,190,253 int []arr={7,27,101,37}; int dengchaA=0; for(int i=1,len=arr.length;i<len;i++){ while(arr[i]<=arr[i-1]){ arr[i]=arr[i]<<1; } dengchaA+=arr[i]-arr[i-1]; } dengchaA=dengchaA/(arr.length-1); for(int i=1,len=arr.length;i<len;i++){ while(arr[i]-arr[i-1]>dengchaA){ arr[i-1]=arr[i-1]<<1; } } for(int a:arr){ System.out.print(a+","); } } } |
|
返回顶楼 | |
发表时间:2011-05-25
其实理解了等差数组的定义和规律,不难解决,我的程序如下,请大家指正:
public class AnotherClass2 { public static void main(String[] args){ int[] old = {1,3,3,1}; restoreArray(old); print(old); } public static void restoreArray(int[] old){//假定old数组一定是由等差数组变换得到的 if(old[1] != 1){//说明第二个数原来为奇数 int gradeValue = old[1]-old[0]; //差额 for(int i=1;i<old.length;i++){ old[i] = old[0]+i*gradeValue; } }else if(old[1] ==1 && old[2]==1){ //第二个和第三个都是1,说明这两个数原来都是偶数,并且偶数之差为偶数,说明等差数组的差也为偶数, throw new IllegalArgumentException("无法推算出原数组"); //说明整个数组都为偶数,且old数组中值均为1,此时无法恢复原数组 }else if(old[1] ==1 && old[2] != 1){ //说明第二个数原来是偶数,同时第三个数原来是奇数,两者之差为奇数,说明等差数组的差也为奇数,所以第一个数为奇数 int gradeValue = (old[2]-old[0])/2; for(int i=1;i<old.length;i++){ old[i] = old[0]+i*gradeValue; } } } public static void print(int[] a){ for(int i=0;i<a.length;i++){ System.out.print(a[i]+" "); } } } |
|
返回顶楼 | |
发表时间:2011-05-26
思路如下: 1. while b=0,1,2,3,前提4的值 2. 计算 x1的真实值= x1<<b,保存到y[1] 3 while a=0,1,2,3,4,前提3的值 4 计算x2的真实值 = x2 << a,保存到y[2] 5 计算step = x2的真实值-x1的真实值 6 while i=3 ,4,5,6,7,n+1 7 xi的真实值=xi-1的真实值+step 8 xi’=除2到奇数(xi) 9 检查xi’是否与x’[i]相等,如相等,则保存到y[i], 跳转step 6;不相等则跳转step3 10 end 11 end 12 end 13 输出y序列即为原始序列。
上述算法最多只能计算2*32-1。 欢迎大家探讨。
|
|
返回顶楼 | |
发表时间:2011-05-26
最后修改:2011-05-26
不可能还原,因为得不到唯一答案。
比如转换后是(1,1)原来可能是(1,1)、(2,2)、(4,4)、(2,4)、(2,8)、(2^i,2^k) |
|
返回顶楼 | |
发表时间:2011-05-26
JackAndroid 写道
思路如下: 1. while b=0,1,2,3,前提4的值 2. 计算 x1的真实值= x1<<b,保存到y[1] 3 while a=0,1,2,3,4,前提3的值 4 计算x2的真实值 = x2 << a,保存到y[2] 5 计算step = x2的真实值-x1的真实值 6 while i=3 ,4,5,6,7,n+1 7 xi的真实值=xi-1的真实值+step 8 xi’=除2到奇数(xi) 9 检查xi’是否与x’[i]相等,如相等,则保存到y[i], 跳转step 6;不相等则跳转step3 10 end 11 end 12 end 13 输出y序列即为原始序列。
上述算法最多只能计算2*32-1。 欢迎大家探讨。
这个算法,是从数学分析的角度来解决问题,有点像动态规划,分析的有道理。 |
|
返回顶楼 | |
发表时间:2011-05-26
最后修改:2011-05-26
公差非0的情况下可通过公差反推。
|
|
返回顶楼 | |