Useful Functions for LeetCode Contests
17 March 2025
[ algorithms , leetcode , helper ]

Here are some of the useful functions to help you with LeetCode contests. Some of them have ideas based on Algorithms for Competitive Programming.


Table of Content

  1. Calculate nCr using Modular Multiplicative Inverse

  2. Example Template


1. Calculate nCr using Modular Multiplicative Inverse

nCr is calculated as: $nCr = \frac{n!}{(n-r)! \, r!}$

To avoid the issues associated with large number operations and potential rounding errors when computing $n!$ divided by $(n-r)!$ and $r!$, we instead convert the divisions into multiplications using the concept of the Modular Multiplicative Inverse. Specifically, the combination $nCr$ is computed as:

$nCr = n! \times \text{inv}((n-r)!) \times \text{inv}(r!)$

where $\text{inv}(a!)$ represents the modular inverse of $a!$.

1.1. Example Code

Constant MOD is set to $1{,}000{,}000{,}007$, a large prime number frequently used in competitive programming and algorithm design to avoid integer overflow and to guarantee the existence of modular inverses for any integer that is relatively prime to the modulus. The arrays fact and invFact are used to store the factorial values and their corresponding modular inverses, respectively.

private int MOD = 1_000_000_007;
private long[] fact, invFact;

The following code snippet initializes a modular exponentiation function designed to compute $\text{base}^{\text{exp}}$ modulo a given modulus. This function operates in $O(\log(\text{exp}))$ ~ $O(\log(\text{N}))$ time complexity, which is achieved by repeatedly halving the exponent at each iteration (using the operation exp >>= 1).

private long modPow(long base, int exp, int mod) {
    long result = 1;
    while (exp > 0) {
        if ((exp & 1) == 1) result = result * base % mod;
        base = base * base % mod;
        exp >>= 1;
    }
    return result;
}

According to Fermat’s Little Theorem, for a prime number $p$, the expression $a^p - a$ is divisible by $p$. Building on this principle, we can derive that the difference $a^{p-2} - a^{-1}$ is likewise divisible by $p$. We first build the factorials. Then, we can build the inverse factorials starting with $\text{inv}(n!) = n!^{MOD-2}$ mod MOD.

private void buildFactorials(int n) {
    fact = new long[n+1];
    invFact = new long[n+1];

    fact[0] = 1;
    for (int i = 1; i <= n; i++) fact[i] = fact[i-1] * i % MOD;

    invFact[n] = modPow(fact[n], MOD-2, MOD);
    for (int i = n-1; i >= 0; i--) invFact[i] = invFact[i+1] * (i+1) % MOD;
}

Based on the factorials and the inverse factorials calculated above, we are now able to calculate nCr:

private long nCr(int r, int n) {
    if (r < 0 || r > n) return 0;
    return (fact[n] * invFact[r] % MOD) * invFact[n-r] % MOD;
}

1.2. Exercises


2. Example Template


import java.io.*;
import java.util.*;

public class Solution {
    public static void main(String[] args) throws Exception {
        // FastScanner io = new FastScanner("");
		FastScanner io = new FastScanner();

		int t = 1; // t = io.nextInt();
		while (t > 0) {

			t--;
		}

		io.close();
    }

    /**
        RESERVED INSTANCES
    */
    static final int mod = 1_000_000_007; // prime number
	static final long oo = (long) 2e18; // infinity number
	static final Random random = new Random();

	/**
		HELPER
		https://tinyurl.com/lamng3-code
	*/

    // ALGEBRA
	static long add(long a, long b) { return (a + b) % mod; }
	static long subtract(long a, long b) { return ((a - b) % mod + mod) % mod; }
	static long multiply(long a, long b) { return (a * b) % mod; }
	static long exp(long base, long exp) { 
		long result = 1;
		while (exp > 0) {
			if ((exp & 1) == 1) result = multiply(result, base);
			base = multiply(base, base);
			exp >>=1;
		}
		return result;
	}

    // NUMBER THEORY
    static int gcd(int a, int b) { 
        while (b > 0) {
            int r = a % b;
            a = b;
            b = r;
        }
        return a;
    }
    static int lcm(int a, int b) { return a * b / gcd(a,b); }

    // ARRAY OPERATIONS
    static void swap(int[] a, int i, int j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; }
    static void shuffle(int[] a) { 
        int n = a.length;
        for (int i = 0; i < n; i++) {
            int ri = random.nextInt(n); // random index
            swap(a, i, ri);
        }
    }

    // SORTING
    static void sort(int[] a) { Arrays.sort(a); }
    static void sort(long[] a) { Arrays.sort(a); }
    static <T extends Comparable<? super T>> void sort(List<T> a) { Collections.sort(a); }
    static void ruffle_sort(int[] a) { shuffle(a); sort(a); }

    // FACTORIALS & nCk
	static long[] factorials = new long[2_000_005];
	static long[] inverseFactorials = new long[2_000_005];
	static void precompute_factorials() {
        int n = factorials.length;
		factorials[0] = 1;
		for (int i = 1; i < factorials.length; i++) {
			factorials[i] = multiply(factorials[i-1], i);
		}
        inverseFactorials[n-1] = exp(factorials[n-1], mod-2);
        for (int i = n-2; i >= 0; i--) {
            inverseFactorials[i] = multiply(inverseFactorials[i=1], i);
        }
	}
    static long nCk(int n, int k) { 
        return multiply(factorials[n], multiply(inverseFactorials[n-k], inverseFactorials[k]));
    }

    /**
        DATA STRUCTURES
    */
    static class MultiSet {
        static TreeMap<Integer, Integer> multiset;
		public MultiSet() { multiset = new TreeMap<>(); }
        static void add(int x) {
            multiset.putIfAbsent(x, 0);
            multiset.put(x, multiset.get(x)+1);
        }
        static void remove(int x) {
            multiset.putIfAbsent(x, 0);
            multiset.put(x, multiset.get(x)-1);
            if (multiset.get(x) <= 0) multiset.remove(x);
        }
    }

    /**
        IO
    */
    static class FastScanner extends PrintWriter {
        private BufferedReader br;
        private StringTokenizer st;
		
		// standard input
        public FastScanner() { this(System.in, System.out); }
		public FastScanner(InputStream i, OutputStream o) {
            super(o);
			st = new StringTokenizer("");
            br = new BufferedReader(new InputStreamReader(i));
        }
		// USACO-style file input
        public FastScanner(String problemName) throws IOException {
            super(problemName + ".out");
			st = new StringTokenizer("");
            br = new BufferedReader(new FileReader(problemName + ".in"));
        }

        // returns null if no more input
        public String next() {
            try {
                while (st == null || !st.hasMoreTokens())
                    st = new StringTokenizer(br.readLine());
                return st.nextToken();
            } catch (Exception e) { }
            return null;
        }
        public int nextInt() { return Integer.parseInt(next()); }  
        public double nextDouble() { return Double.parseDouble(next()); }   
        public long nextLong() { return Long.parseLong(next()); }   
    }
}


Sign-off

Congratulations on making it this far! Best of luck in your future competitions!