Find last digit of Nth Fibonacci Number
EasyUpdated: Sep 18, 2025
Problem
Given an integer n (possibly very large), return the last digit (units digit) of the n-th Fibonacci number F(n).
- Input: integer
n(may be provided as a large integer or as a decimal string). - Output: single digit
F(n) mod 10.
Examples
Example 1
Input: n = 0
Output: 0
Example 2
Input: n = 2
Output: 1
Example 3
Input: n = 7
Output: 3
Solution
Three straightforward approaches are useful here:
- Method 1 — naive Fibonacci (for completeness)
- Method 2 — iterative computation with modulus
10(O(n) time, O(1) space) - Method 3 — exploit cyclicity (Pisano period for modulus 10 is 60) to get an O(1) answer after precomputation
Method 1 — Naive Fibonacci
Intuition
Compute F(n) directly and take its last digit. This is straightforward but impractical for large n because Fibonacci numbers grow exponentially.
Approach
- Use two variables
aandbto iteratively build Fibonacci numbers up tonand returnF(n) % 10.
Code
C++
class Solution {
public:
long long fib_naive(unsigned long long n) {
if (n == 0) return 0;
if (n == 1) return 1;
long long a = 0, b = 1;
for (unsigned long long i = 2; i <= n; ++i) {
long long nxt = a + b; a = b; b = nxt;
}
return b;
}
};
Complexity
- ⏰ Time complexity:
O(n)to computeF(n)by iteration. - 🧺 Space complexity:
O(1)extra space.
Method 2 — Iterative modulo 10
Intuition
We only need the last digit, so compute Fibonacci terms modulo 10 during iteration; arithmetic stays small and safe.
Approach
- Maintain
a = 0, b = 1and iteratentimes updatinga, b = b, (a+b) % 10. - If
nis provided as a decimal string, computen % k(for k = cycle length if used) as needed; otherwise iteratensteps.
Code
C++
class SolutionMod {
public:
int last_digit(unsigned long long n) {
int a = 0, b = 1;
if (n == 0) return 0;
for (unsigned long long i = 1; i <= n; ++i) {
int nxt = (a + b) % 10; a = b; b = nxt;
}
return a % 10;
}
};
Go
package main
func LastDigitFib(n uint64) int {
a, b := 0, 1
if n == 0 { return 0 }
for i := uint64(1); i <= n; i++ {
a, b = b, (a+b) % 10
}
return a % 10
}
Java
class Solution {
public int lastDigit(long n) {
int a = 0, b = 1;
if (n == 0) return 0;
for (long i = 1; i <= n; ++i) {
int nxt = (a + b) % 10; a = b; b = nxt;
}
return a % 10;
}
}
Kotlin
class Solution {
fun lastDigit(n: Long): Int {
var a = 0; var b = 1
if (n == 0L) return 0
for (i in 1..n) { val nxt = (a + b) % 10; a = b; b = nxt }
return a % 10
}
}
Python
class Solution:
def last_digit(self, n: int) -> int:
a, b = 0, 1
if n == 0:
return 0
for _ in range(1, n + 1):
a, b = b, (a + b) % 10
return a % 10
Rust
pub struct Solution;
impl Solution {
pub fn last_digit(mut n: u128) -> u8 {
if n == 0 { return 0 }
let (mut a, mut b) = (0u8, 1u8);
for _ in 1..=n {
let nxt = (a + b) % 10; a = b; b = nxt;
}
a
}
}
Complexity
- ⏰ Time complexity:
O(n)— performsniterations. - 🧺 Space complexity:
O(1)extra space.
Method 3 — Precompute cycle (Pisano period for modulus 10)
Intuition
For modulus 10 the Pisano period is 60: the sequence of last digits repeats every 60 terms. So F(n) mod 10 = F(n % 60) mod 10. Precompute the first 60 last digits and answer any query in O(1).
Approach
- Precompute array
cycle[0..59]withcycle[i] = F(i) mod 10. - Compute
idx = n % 60(ifnis a decimal string computeidxby streaming digits:idx = (idx*10 + d) % 60). - Return
cycle[idx].
Edge cases:
n == 0->0.
Code
C++
class SolutionPisano {
public:
int last_digit(unsigned long long n) {
static int cycle[60] = {0};
static bool init = false;
if (!init) {
init = true; cycle[0] = 0; cycle[1] = 1;
for (int i = 2; i < 60; ++i) cycle[i] = (cycle[i-1] + cycle[i-2]) % 10;
}
return cycle[n % 60];
}
};
Go
package main
var pisano60 = func() [60]int {
var c [60]int
c[0], c[1] = 0, 1
for i := 2; i < 60; i++ { c[i] = (c[i-1] + c[i-2]) % 10 }
return c
}()
func LastDigitFibPisano(n uint64) int { return pisano60[n % 60] }
Java
class Solution {
private static final int[] CYCLE = new int[60];
static {
CYCLE[0] = 0; CYCLE[1] = 1;
for (int i = 2; i < 60; ++i) CYCLE[i] = (CYCLE[i-1] + CYCLE[i-2]) % 10;
}
public int lastDigit(long n) { return CYCLE[(int)(n % 60)]; }
}
Kotlin
object Solution {
private val CYCLE = IntArray(60).also { it[0]=0; it[1]=1; for (i in 2..59) it[i]=(it[i-1]+it[i-2])%10 }
fun lastDigit(n: Long) = CYCLE[(n % 60).toInt()]
}
Python
class Solution:
CYCLE = [0,1] + [0]*58
for i in range(2,60):
CYCLE[i] = (CYCLE[i-1] + CYCLE[i-2]) % 10
def last_digit(self, n: int) -> int:
return Solution.CYCLE[n % 60]
def last_digit_str(self, s: str) -> int:
r = 0
for ch in s:
r = (r*10 + (ord(ch)-48)) % 60
return Solution.CYCLE[r]
Rust
pub struct Solution;
impl Solution {
fn pisano60() -> [u8;60] {
let mut c = [0u8;60]; c[0]=0; c[1]=1;
for i in 2..60 { c[i] = (c[i-1] + c[i-2]) % 10 }
c
}
pub fn last_digit(n: u128) -> u8 { let c = Self::pisano60(); c[(n % 60) as usize] }
}
Complexity
- ⏰ Time complexity:
O(1)after precomputation (precompute costO(60)negligible). Overall per-query timeO(1). - 🧺 Space complexity:
O(1)extra space for the 60-entry cycle.