Back to Beginner: I/O, Arithmetic, Loops
Q16Question 16 of 30

Factorial: print N! as the product of all integers from 1 to N

Key Concepts
  • Factorial of N is the product of all integers from 1 to N; by definition 0! = 1 because an empty product is the multiplicative identity.
  • The iterative algorithm uses a running product starting at 1 and multiplies by each integer from 1 to N.
  • The zero case needs no special code: the loop condition fails immediately and the product stays at 1.
  • Factorials overflow a Java long past 20!, so banking code uses BigInteger for exactness.
  • Negative input is undefined and must be rejected with IllegalArgumentException.
  • The time complexity is O(n) with one multiplication per step and O(1) space apart from the BigInteger itself.

Definition

Factorial is a running product that starts at one and multiplies in every integer from one to N, and because an empty product is one, zero factorial is one.
  • Factorial (N!) – the product of every integer from 1 up to N.
  • Zero factorial – 0! = 1 because the product of no numbers is the multiplicative identity.
  • Running product – initialize at 1, multiply by each counter value from 1 to N.
  • Overflow – a Java long overflows past 20!; use BigInteger for arbitrary-precision results.
  • Negative guard – factorial is undefined for negative numbers; reject with IllegalArgumentException.

National Bank of India calculates how many different orders N pending cheques can be processed in. The first cheque can go in any of N slots, the next in N-1 slots, and so on down to one. Multiplying those choices is exactly N!. Rajesh asks how many ways his five cheques can be arranged, and the answer is 120.

Understanding the Concepts

What is the iterative factorial algorithm?

The algorithm needs one accumulator (result) and one counter (i). The accumulator starts at 1, the multiplicative identity. The counter walks from 1 to N, and each step multiplies: result = result * i. When the loop finishes, result holds N!.

JAVA
package com.bank.service;

import java.math.BigInteger;

public class FactorialCalculator {

    public static BigInteger factorial(int n) {
        if (n < 0) {
            throw new IllegalArgumentException("Factorial undefined for negative: " + n);
        }
        BigInteger result = BigInteger.ONE;
        for (int i = 2; i <= n; i++) {
            result = result.multiply(BigInteger.valueOf(i));
        }
        return result;
    }

    public static void main(String[] args) {
        System.out.println("5! = " + factorial(5));
        System.out.println("0! = " + factorial(0));
        System.out.println("20! = " + factorial(20));
    }
}
TEXT
5! = 120
0! = 1
20! = 2432902008176640000

Why does the zero case work without special code?

When N is zero, the loop condition i <= 0 is false immediately (since i starts at 2), so the body never runs and result stays at its initial value of 1. That is exactly the mathematical definition of 0!.

Why use BigInteger for banking?

Factorials grow explosively. 13! exceeds Integer.MAX_VALUE, and 21! exceeds Long.MAX_VALUE. Using a primitive type silently wraps around to a wrong or negative number. In a financial system, a silently wrong count is dangerous.

JAVA
// Wrong: long overflows silently
long result = 1;
for (int i = 1; i <= 25; i++) result *= i;
System.out.println(result); // 7034535277573963776 (WRONG)

// Correct: BigInteger is exact
System.out.println(factorial(25));
// 15511210043330985984000000

What is the flowchart?

DIAGRAM
  Start → Read N → result=1, i=1
    │
    ▼
  i <= N? ──No──→ Print result → End
    │ Yes
    ▼
  result = result * i
  i = i + 1
    └──→ back to i <= N?

What are common mistakes?

JAVA
// Wrong: starting result at 0
BigInteger result = BigInteger.ZERO;
// Every multiplication gives zero!

// Correct: start at 1 (multiplicative identity)
BigInteger result = BigInteger.ONE;

How is iterative different from recursive?

The iterative version uses constant stack space and cannot overflow the stack. The recursive version matches the mathematical definition but adds one stack frame per call, risking StackOverflowError for large N. Both produce the same result.

What should a senior engineer know?

For repeated queries, cache previously computed factorials in a lookup table. For very large N, specialized libraries use divide-and-conquer multiplication (split-recursive) which is faster than the naive linear multiply chain because large BigInteger multiplications are super-linear in the number of digits.

What are common interview follow-up questions?

  • How many trailing zeros does N! have? (Count factors of 5.)
  • Can you compute N! modulo a prime efficiently? (Yes, just mod at each step.)
  • What is the time complexity considering BigInteger multiplication cost?

Visual Overview

DIAGRAM
  ┌─────────┐
  │  Start  │
  └────┬────┘
       ▼
  ┌──────────┐
  │  Read N  │
  └────┬─────┘
       ▼
  ┌────────────────┐
  │ result=1, i=1  │
  └────┬───────────┘
       ▼
  ┌──────────┐  No   ┌──────────────┐
  │ i <= N?  │──────→│ Print result │→ End
  └────┬─────┘       └──────────────┘
       │ Yes
       ▼
  ┌──────────────────┐
  │ result=result*i  │
  │ i = i + 1        │
  └────┬─────────────┘
       └──→ back to i <= N?

Key Takeaway

Factorial of a non-negative integer N is the product of every integer from one up to N, and by definition zero factorial is one because the product of no numbers is the multiplicative identity. The iterative algorithm starts a running product at one, multiplies by each integer from one to N, and the zero case needs no special code because the loop condition fails immediately and the product stays at one.

The real-world subtlety for banking is overflow. Factorials grow astonishingly fast, and a Java long overflows past twenty factorial, silently producing a wrong or negative number. In a financial system that is unacceptable, so the computation uses BigInteger, which has arbitrary precision and never overflows. A guard clause rejects negative input because factorial is undefined there.

In a banking project at National Bank of India, an audit-sampling tool needed to know how many distinct orders a small batch of cheques could be processed in, which is exactly N!. The FactorialCalculator used BigInteger and validated the input. For five cheques it reported 120, and because BigInteger was used it stayed exact for much larger batches too.

Remember one sentence: seed the product at one because one is the multiplicative identity, and use BigInteger so the growing result never overflows.

---

Share
Use ← → arrow keys to navigate