关于三星面试题中的一点很有趣的现象,谁给证明一下
原题如下:已知:
a[0] = 0;
a[1] = 1;
...
...
a[2*i] = a[i];
a[2*i+1] = a[i] + a[i+1];
问题:
给定任意一个i(0 <i <2000000)
求a[0]到a[i]之间的最大值,以及其下标。
我的解法:
遍历 a[p]到a[i]找最大值即可
其中 p为2^n (其中,2^(n+1)为小于i的最接近2的幂的数)
例如: p=69;则n=5,遍历a[32] 到 a[69]即可!
观察一下解的状况
2:1
3:2
4:1
5:3
6:2
7:3
8:1
9:4
10:3
11:5
12:2
13:5
14:3
15:4
16:1
17:5
18:4
19:7
20:3
21:8
22:5
23:7
24:2
25:7
26:5
27:8
28:3
。。。
让我想起了帕斯卡三角形,但是不完全一样,构建如下,每2^n 为一层,第一层为0-2,第二层为2-4,第三层4-8,8-16, 16-32...
------------------1 2 1
----------------1 3 2 3 1
---------------1 4 3 5 2 5 3 4 1
-。。。
应用帕斯卡三角形中的原则,每项等于头顶上两项相加。不同的是,每层元素都落到下一层。也可以先把某层落到下一层,然后相邻元素相加插在落下的元素之间。
好了,怎样确定每一层中最大的元素的下标呢?例如,8-16(图中第三层)边界是 8,16 old = 8,new = 16,然后找到中点 (8+16)/2 = 12 令 new = 12 (old = 8 or old = 16,因为每层元素是对称的) ,然后, (8 + 12)/2 = 10 (new = 10, old = 12), 再(12 + 10)/2 = 11 (new = 11,old =10),但是 new(11) 和 old(10) 之间没有数字,所以,下标为11的元素为最大值。
更有趣的现象是,已知下标,如果我们按照题目给定的公式去求值,可能很慢,观察每行中最大值的规律。
第0行算是1,第一行是(0-2) 最大值2,第二行(2-4) 3,第三行(4-8)最大值就是5,第四行(8-16) 8,第五行(16-32) 13...
哈,老朋友,费波那契。
现在我要问的是,那位朋友能够给出比较完整的数学推理,因为我只是观察而已。还有一些细节的工作,例如,给定的i 不是2的幂,怎么办,那要看最大的2的幂与i之间是否包含拥有最大值的那个下标,如果不包含怎么办?我这里抛砖引玉,谁给个比较完整的方案。