Fibonacci序列使用以下递归公式定义:
F(0) = 0
F(1) = 1
F(M) = F(M - 1) + F(M - 2) if M >= 2
一只小青蛙想要到达河的另一边。青蛙最初位于河的一岸(位置-1)并且想要到达另一岸(位置N)。青蛙可以跳过任何距离F(K),其中F(K)是第K个斐波那契数。幸运的是,河上有许多叶子,青蛙可以在叶子之间跳跃,但只能在N位置的银行方向上跳跃。
河上的叶子用零索引数组A表示,该数组由N个整数组成。数组A的连续元素表示河流上从0到N-1的连续位置。数组A仅包含0和/或1:
0表示没有叶子的位置; 1表示包含叶子的位置。 目标是计算青蛙可以到达河的另一侧的最小跳跃次数(从位置-1到位置N)。青蛙可以在位置-1和N(河岸)和每个包含叶子的位置之间跳跃。
例如,考虑数组A:
A[0] = 0
A[1] = 0
A[2] = 0
A[3] = 1
A[4] = 1
A[5] = 0
A[6] = 1
A[7] = 0
A[8] = 0
A[9] = 0
A[10] = 0
青蛙可以进行三次跳跃,长度为F(5)= 5,F(3)= 2,F(5)= 5.
写一个函数:
功能解决方案(A);
给定由N个整数组成的零索引数组A,返回青蛙可以到达河流另一侧的最小跳跃次数。如果青蛙无法到达河的另一侧,则该函数应返回-1。
例如,给定:
A[0] = 0
A[1] = 0
A[2] = 0
A[3] = 1
A[4] = 1
A[5] = 0
A[6] = 1
A[7] = 0
A[8] = 0
A[9] = 0
A[10] = 0
该函数应返回3,如上所述。
假设:
N是[0..100,000]范围内的整数; 数组A的每个元素都是一个整数,可以具有以下值之一:0,1。 复杂度:
预期的最坏情况时间复杂度为O(N * log(N)); 预期的最坏情况空间复杂度是O(N),超出输入存储(不计入输入参数所需的存储)。 可以修改输入数组的元素。
//下面是我在Javascript中未完成的代码。我无法解决它......
function solution(A) {
var fibs = [];
var length = A.length;
for(var i = 0; i < length; i++) {
fibs.push(fib(i));
}
// [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ]
var currentLeafIndex = -1;
while(currentLeafIndex < length + 1) {
var possibleLeaves = [];
i = 0;
while(currentLeafIndex + fibs[i]< length) {
var thisIndex = currentLeafIndex + fibs[i];
if(A[thisIndex] === 1 ) {
possibleLeaves.push(thisIndex);
}
i++;
}
console.log(possibleLeaves);
return; // debug
}
}
function fib(number) {
/*
F(0) = 0
F(1) = 1
F(M) = F(M - 1) + F(M - 2) if M >= 2
*/
if(number === 0) {
return 0;
}
if(number === 1) {
return 1;
}
return fib(number -1) +fib(number -2);
}
var inputA = [0,0,0, 1,1,0, 1,0,0, 0,0];
var result = solution(inputA);
console.log("result is: " + result);
答案 0 :(得分:0)
这看起来像是典型的动态编程问题:杆切割问题。设置重复,如:
斐波纳契序列中所有k的最小跳跃(n)=最小(n-k)
换句话说,进行一次跳跃,然后递归找到你跳过一次所需的跳跃次数。如果没有可能的跳转,则返回任意高的数字,如100,000。
注意:递归公式非常昂贵,因此存储值而不是重复重新计算