1. 题目描述

给你数字k,请你返回和为k的斐波那契数字的最少数目,其中,每个斐波那契数字都可以被使用多次。

斐波那契数字定义为:

F1 = 1

F2 = 1

Fn = Fn-1 + Fn-2 , 其中 n > 2 。

数据保证对于给定的k,一定能找到可行解。

示例 1:

输入:k = 7
输出:2
解释:斐波那契数字为:1,1,2,3,5,8,13,……
对于 k = 7 ,我们可以得到 2 + 5 = 7

示例 2:

输入:k = 10
输出:2
解释:对于 k = 10 ,我们可以得到 2 + 8 = 10

示例 3:

输入:k = 19
输出:3
解释:对于 k = 19 ,我们可以得到 1 + 5 + 13 = 19

提示:

1 <= k <= 10^9

来源:力扣(LeetCode)

2. 解题思路

对于一个给定的数字k,注意到总是存在一个可行解的。那么在最优的方案下,它的拆分数中一定有一个最大的不超过kFibonacci数。

只要注意到这样一个事实,越小的数,最优方案的拆分数就越少。那么原问题就变为一个减而治之的问题。设不超过的k的最大的斐波那契数为m,则m + (k - m)一定是一个可行解。我们减去的部分越大,剩下的部分就越少。逐次拆分,最终就能得到最优方案的拆分数。

class Solution {
public:
int findMinFibonacciNumbers(int k) {
int count = 0;
while(k != 0) {
int i = 1, j = 1; // 计算不超过k的最大的fibonacci数
while (j <= k) {
int tmp = j;
j = i + j; i = tmp;
}
k -= i; count++;
}
return count;
}

};

算法复杂度

  • 时间复杂度:求一个不超过kFibonacci数的时间复杂度应当是。那么最坏情况下的时间复杂度应该是。最好情况下的时间复杂度为
  • 空间复杂度: