论坛首页 综合技术论坛

谷歌的一道面试题,请大家集思广益

浏览 38420 次
精华帖 (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的情况。
这个面试题,应该求的是最小和等差数组(范围定义在整数范围内)
0 请登录后投票
   发表时间:2011-05-25  
如果没有额外的限定条件的话,原数列是得不到的。
因为等差数列的每一项乘以一个同样的因子,得到的仍然是一个等差数列

如果有限定条件,比如最少有一个是奇数,则理论上应该可以。
0 请登录后投票
   发表时间:2011-05-25  
ubotutwin 写道
lzyzizi 写道
Cross_Lee 写道
2234  下来也是 1131。
所以只根据这些条件是不能反向得到唯一的1234的。

注意是等差数列,同学

 

假设如果有算法能将一个处理后的数组还原到1、2、3、4,那怎么判断原数组是1、2、3、4还是2、4、6、8?

嗯     +1

0 请登录后投票
   发表时间:2011-05-25  
fflame 写道
如果没有额外的限定条件的话,原数列是得不到的。
因为等差数列的每一项乘以一个同样的因子,得到的仍然是一个等差数列

如果有限定条件,比如最少有一个是奇数,则理论上应该可以。


又仔细考虑一下,发现之前考虑的不完全:
按题目要求:
等差数组234和等差数组432处理以后得到的结果都是:
131
于是失败

也许只有3个数的数列太短,多于3个可以?需要去讨论边界了,麻烦……
0 请登录后投票
   发表时间: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+",");
		}
	}
	
}
0 请登录后投票
   发表时间: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]+" ");
		}
	}
}

0 请登录后投票
   发表时间: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。

欢迎大家探讨。

 

 

  • 大小: 26.2 KB
0 请登录后投票
   发表时间:2011-05-26   最后修改:2011-05-26
不可能还原,因为得不到唯一答案。
比如转换后是(1,1)原来可能是(1,1)、(2,2)、(4,4)、(2,4)、(2,8)、(2^i,2^k)
0 请登录后投票
   发表时间: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。

欢迎大家探讨。

 

 

这个算法,是从数学分析的角度来解决问题,有点像动态规划,分析的有道理。

0 请登录后投票
   发表时间:2011-05-26   最后修改:2011-05-26
公差非0的情况下可通过公差反推。
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics