【问题标题】:Last Digit of a Large Fibonacci Number fast algorithm大斐波那契数快速算法的最后一位
【发布时间】:2019-06-26 01:54:10
【问题描述】:

我正在尝试使用 java 解决斐波那契,但我的代码需要很长时间才能处理大数字。

问题描述 任务。给定一个整数 ????,找出 ????th 斐波那契数 ???????? 的最后一位(即 ???????? mod 10)。

输入格式。输入由一个整数组成 ????.

约束。 0 ≤ ???? ≤ 10⁷.

输出格式。输出????????的最后一位。

我的代码:

public class FibonacciLastDigit {

private static int getFibonacciLastDigitNaive(int n) {
    if (n <= 1) {
        return n;
    }
    BigInteger first = BigInteger.ZERO;
    BigInteger second = BigInteger.ONE;
    BigInteger temp;

    for (int i = 1; i < n; i++) {
        temp = first.add(second);
        first = second;
        second = temp;
    }
    return second.mod(BigInteger.TEN).intValue();
}

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int n = scanner.nextInt();
    System.out.println(getFibonacciLastDigitNaive(n));
}}

如果输入 = 613455,我的代码将失败,获取值需要 30 秒,最大允许时间为 1.5 秒。

我不得不使用大整数,因为 long 不够。

【问题讨论】:

  • 我不明白.. 约束说 n
  • 如果我阻止他输入超过 107 个测试用例失败,我不知道为什么会发生这种情况,所以我不得不删除这个约束
  • 是的,它注定要失败,不是吗?这意味着不会有任何高于 107 的输入。此外,您不需要大数字。 @meowgoesthedog 的提示非常好。
  • 我预计“107”应该是 10⁷。我进行了修改以解决问题。

标签: java algorithm fibonacci biginteger


【解决方案1】:

斐波那契数的最后一位数字有一个循环。每 60 个数字重复一次。因此,只需构建前 60 个数字的最后一位数字的表,然后对输入进行模 60 运算并进行查表。

您可以在任何在线(或离线)斐波那契数表中看到循环。底部有一个链接。

为了建立表格,对于每个计算出的数字,如果超过 9,您可以减去 10,因为您只需要最后一位,并且每个数字的最后一位仅取决于前两个数字的最后一位。您可以使用int 数学(您既不需要long 也不需要BigInteger)。

链接:The first 300 Fibonacci numbers, factored

【讨论】:

  • 如果这不是一个 comp sci 练习(即使是这样),那么这应该是唯一可以接受的答案。因为这个算法几乎可以保证恒定的计算复杂度。
【解决方案2】:

您的实现确实很幼稚,因为您被要求获取斐波那契数的最后一位而不是实际的斐波那契数本身。您只需要跟踪最后一位数字,其他数字无关紧要。

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int n = scanner.nextInt();
    System.out.println(getFibonacciLastDigit(n));
}

private static int getFibonacciLastDigit(int n) {
    if (n <= 1) {
        return n;
    }
    int first = 0;
    int second = 1;
    int temp;

    for (int i = 1; i < n; i++) {
        temp = (first + second) % 10;
        first = second;
        second = temp;
    }
    return second;
}

【讨论】:

  • 这也不是最优的,因为除了另一个答案中的算法之外,还有一个算法需要 O(log(n)) 步骤。
【解决方案3】:

这里附上一个c++程序,可以用java写程序的逻辑。通过这段代码,我们只需要找到第 60 个斐波那契数。而且这将执行非常快,也不需要持有大量。

#include <iostream>

using namespace std;

long long int findOutTheFibonacciNumber(int n)
{
    int number = n % 60;
    if (number <= 1)
    {
        return number;
    }
    else
    {
        long long int a = 0;
        long long int b = 1;
        long long int c = 1;
        for (int i = 2; i <= number; i++)
        {
            c = (long long)a + b;
            a = b;
            b = c;
        }
        return c % 10;
    }
}

int main()
{
    int n;
    cin >> n;
    cout << findOutTheFibonacciNumber(n);
    return 0;
}

【讨论】:

    【解决方案4】:

    py中的代码必须是

    lookup = {0:0,1:1}
    N = int(input())
    for i in range(2,N+1):
           lookup[i] = (lookup[i-1] + lookup[i-1])%10
    print(lookup[N])
    

    【讨论】:

      猜你喜欢
      • 2020-05-24
      • 2019-05-29
      • 2012-11-29
      • 1970-01-01
      • 2016-09-11
      • 1970-01-01
      • 1970-01-01
      • 2020-08-26
      • 1970-01-01
      相关资源
      最近更新 更多