求一个斐波那契数在斐波那契数列中的下标

132 阅读2分钟

给出一个斐波那契数列中的某一项 num,然后求出这个斐波那契数在斐波那契数列里的下标值 index

一、不考虑性能情况下

思路

  1. 先实现一个求斐波那契数的函数
  2. 初始化下标 index = 1, flag=true标记
  3. while 循环判断flag,如果 求得的斐波那契数不等于num,则index + 1, 如果相对,则flag=false,跳出循环

上代码

// 1 ,1 ,2 ,3 ,5 ,8, 13 ,21 ,......
const fbn = (n) => {
  if (n == 1 || n == 2) {
	return 1
  } else {
	return fbn(n-2) + fbn(n-1)
  }
}
console.log('fbn(n)=', fbn(5))

function getIndexByNum(num) {
  let flag = true
  let index = 1
  while (flag) {
    let val = fbn(index)
    if (val === num) {
      flag = false
    } else {
      index++
    }
  }
  return index - 1
}

console.log('fbn-index=', getIndexByNum(13))

// fbn(n)= 5
// fbn-index= 6

思考

上面代码的问题: 每次while循环的时候, fbn() 函数都会从头开始计算,没有沿用上一次循环计算出来的结果(斐波那契数的性质:fbn(n) = fbn(n-2) + fbn(n-1)),造成了性能上的浪费。

我们可以试着把上一步计算出来的值保存下来,这样当进行新一轮的循环时,直接把保存的值相加即可,算法时间复杂度变成 n,以下是代码实现。

二、性能优化

思路

  1. 处理边界问题
  2. 初始化下标 index = 3, flag=true标记
  3. 从第四个数(也就是3)开始写逻辑,有:pre1 = 2, pre2 = 1(初始化前面两个的值)
  4. 初始化一个临时变量 tmp, 用于暂存 pre1 的值,用来更新 pre2的值
  5. while 循环判断flag,如果 求得的斐波那契数不等于num,则index + 1, 如果相对,则flag=false,跳出循环

上代码

// 1 ,1 ,2 ,3 ,5 ,8, 13 ,21 ,......
function getIndexByNum(num) {
  if (num < 1) {
    console.log('不是斐波那契数');
    return
  }
  if (num <= 2) {
    return num
  }

  let pre1 = 2
  let pre2 = 1
  let tmp = ''

  let flag = true
  let index = 3
  while (flag) {
    // const val = fbn(index)
    const val = pre1 + pre2 // 3
    tmp = pre1 // 2
    pre1 = val // 3
    pre2 = tmp // 2
    console.log('pre1=', pre1, 'pre2=',pre2);
    if (val == num) {
      flag = false
    } else {
      index++
    }
  }
  return index
}

console.log('fbn-index=', getIndexByNum(8))

🎈🎈🎈

🌹 持续更文,关注我,你会发现一个踏实努力的宝藏前端😊,让我们一起学习,共同成长吧。

🎉 喜欢的小伙伴记得点赞关注收藏哟,回看不迷路 😉

✨ 原创,欢迎大家评论交流,转发请注明出处,谢谢