给你数字 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


    1. class Solution {
    2. static List<Integer> nums = new ArrayList<>();
    3. static {
    4. int a = 1, b = 1;
    5. nums.add(1);
    6. while (true) {
    7. int c = a + b;
    8. nums.add(c);
    9. a = b;
    10. b = c;
    11. if (a > 1e9) break;
    12. }
    13. }
    14. public int findMinFibonacciNumbers(int k) {
    15. int l = 0, r = nums.size() - 1;
    16. int res = 0;
    17. while (k != 0) {
    18. //二分找第一个小于等于k的数
    19. while (l < r) {
    20. int mid = l + r + 1 >> 1;
    21. if (nums.get(mid) <= k) l = mid;
    22. else r = mid - 1;
    23. }
    24. res++;
    25. k -= nums.get(l);
    26. l = 0; //重置l
    27. }
    28. return res;
    29. }
    30. }

    贪心

    1. class Solution {
    2. public int findMinFibonacciNumbers(int k) {
    3. int a = 1, b = 1;
    4. //我们直接递推找出第一个小于等于k的数然后模拟
    5. while (b <= k) {
    6. int c = a + b;
    7. a = b; b = c;
    8. }
    9. int res = 0;
    10. while (k != 0) {
    11. if (k >= b) {
    12. k -= b;
    13. res ++;
    14. }
    15. int c = b - a;
    16. b = a; a = c;
    17. }
    18. return res;
    19. }
    20. }