We compute from the smaller side $\frac{n-k+1}{1}$ to avoid the potential non-divisible error caused by $\frac{n}{k}$.
// Author: github.com/lzl124631x
// Time: O(min(K, N - K))
// Space: O(1)
int combination(int n, int k) {
k = min(k, n - k); // Since we loop in range [1, k], we make sure `k` is smaller than `n - k`
long ans = 1;
for (int i = 1; i <= k; ++i) {
ans = ans * (n - k + i) / i; // compute from the smaller side
}
return ans;
}
To avoid overflow, we will be asked to return the answer modulo some prime number (1e9+7 on LeetCode).
We can't change the above solution to ans = ans * (n - k + i) / i % mod because after a previous modulo operation, ans * (n - k + i) might not be divisible by i.
We need to use this equation:
Cnkā=Cnā1kā1ā+Cnā1kā
Memo: Picking k elements from n elements is the same as the sum of the following:
Pick the first element, and pick k - 1 elements from the rest n - 1 elements, i.e. $C_{n-1}^{k-1}$
Skip the first element, and pick k elements from the rest n - 1 elements, i.e. $C_{n-1}^k$
This can be computed using Pascal Triangle and Dynamic Programming.