题目描述
求从坐标零点到坐标n的最小步数,一次只能沿横坐标轴向左或向右移动2或3。注意:途经的坐标可以为负数。
输入描述
坐标点n
输出描述
输出从坐标零点移动到坐标n的移动步数。
示例一
输入
4
输出
2
说明
从坐标零点移动到4,最小需要两步,即向右移2步,再向右移2步。
备注
1≤n≤109
求解
这个问题是一个典型的动态规划问题,主要解决的是如何从0点到达n点的最小步数。每次移动只能是2步或3步,且可以向左或向右移动。虽然可以向左移动,但从0点开始,向右移动到达任何非负整数点n总是更快的,所以我们的目标是寻找最小步数来到达非负整数n。
分析:从后向前推,走向n时,它的前一步一是 n-2,或者是 n-3,这样只需要一步就能走到n,在其他位置最少需要2步,可以得到一个公式: fn(n) = Math.min(fn(n-2)+1 , fn(n-3)+1)
n=1时,fn(1) = 2;
n=2时,fn(2) = 1;
n=3时,fn(3) = 1;
.....
利用递归求解
function fn(n){
if(n == 1){
return 2;
}
if(n == 2 || n== 3){
return 1
}
return Math.min(fn(n-2)+1,fn(n-3)+1)
}
解法优化,n的范围是1到10的9次方,n较大时,使用递归可能栈溢出。对此可以使用循环来优化。
function fn(n){
let step1 = 2,step2 = 1,step3=1;
if(n == 1){
return step1;
}
if(n == 2 || n== 3){
return step2
}
for(let i = 4;i<=n;i++){
let step4 = Math.min(Number(step2)+1,Number(step1)+1);
step1 = step2;
step2 = step3;
step3 = step4
}
return step3;
}