skip to content

Counting & Combinatorics

Product and sum rules, binomial identities, inclusion-exclusion at depth, recurrence closed forms, and collision and union bounds. Interviewers probe it when a state space has to be sized.

part ofComputer science fundamentalsoverview, primer and where to startread it →
on this pageshow

questions

25

In the expansion of (1 + x)^n, why does the coefficient of x^k count the k-member reviewer sets drawn from n engineers?

level: middleimportance: must knowfreq 58%

answer

  1. one factor for each engineer
  2. every factor offers exactly two terms
  3. x means joining, 1 means staying off
  4. collect terms that share an exponent
  5. the exponent records the set size

basics

~20 s

Expanding (1 + x)^n means one (1 + x) factor per engineer, and each factor contributes either 1 (stay off the review) or x (join it). A product becomes x^k exactly when k engineers contributed x, so its coefficient counts k-member sets.

solid answer

~50 s

Write the roster as one factor `(1 + x)` per engineer. Expanding by distributivity means forming every product that picks exactly one term out of each factor, so each expanded product is a decision string: `1` for an engineer who stays off the review, `x` for one who joins. A string with k copies of `x` multiplies out to `x^k`, and two different strings with the same k give the same monomial, so collecting like terms adds one unit to the coefficient of `x^k` for every k-member set. The coefficient is therefore a count, not a formula you have to derive first: it is the number of ways to choose which k of the n factors contributed `x`, which is exactly C(n, k). Nothing here requires x to be a number; it is a bookkeeping marker whose exponent records the size of the chosen set.

code

pseudocode · 10 lines
pseudocode
coeffs = [1]                      // the polynomial 1, before any engineer is added

for each engineer in roster:      // multiply the running polynomial by (1 + x)
    next = array of zeros, length coeffs.length + 1
    for k = 0 to coeffs.length - 1:
        next[k]     = next[k]     + coeffs[k]   // this engineer stays off the review
        next[k + 1] = next[k + 1] + coeffs[k]   // this engineer joins the review
    coeffs = next

// coeffs[k] is now the number of k-member reviewer sets on the roster

go deeper

for a junior

Remember the shape: n factors of (1 + x), each engineer choosing between two terms, and an exponent that records how many chose to join. The coefficient is a headcount of possibilities, not a formula to memorise.

for a middle

Be able to run the expansion out loud: distributivity forms one product per decision string, like monomials are then collected, and the collecting step is the tally. Explain why order never enters, since each factor is consulted once.

for a senior

Show that the reading survives a constraint change. If one engineer must be on the review, that factor loses its 1; if a pool cannot supply more than two, the surviving strings are the ones you count. Reason about the model, not the algebra.

for a principal

Treat the expansion as a modelling choice you are accountable for. It assumes independent per-engineer decisions and interchangeable people; when either assumption is false in the real roster, say so before the count is quoted in a design decision.

## What the expansion actually is `(1 + x)^n` is not a formula waiting to be looked up; it is **n copies of the factor `(1 + x)` multiplied together**. Model a roster of n engineers by giving each engineer one factor. Expanding the product means applying distributivity until no parentheses remain, and distributivity has a precise combinatorial meaning: **the expanded sum contains one term for each way of picking exactly one summand out of every factor**. Each factor offers two summands, so before any like terms are collected there are 2^n products. Each of those products is a decision string over the roster: - pick `1` from an engineer's factor - that engineer **stays off** the review; - pick `x` from an engineer's factor - that engineer **joins** the review; - multiply the picks together - the `1`s vanish and the `x`s accumulate. A string that picked `x` from exactly k factors multiplies out to `x^k`. The exponent is therefore not an arbitrary label: **it is the size of the chosen reviewer set**. ## Why collecting like terms performs the count Two different decision strings can produce the same monomial. Choosing engineers A and B gives `x^2`; so does choosing C and D. Collecting like terms adds those contributions, so the coefficient of `x^k` accumulates **one unit per distinct set of k engineers**. | step in the algebra | what it means on the roster | |---|---| | one factor `(1 + x)` per copy | one engineer, faced with one binary decision | | picking a summand from each factor | building one candidate reviewer set | | the monomial `x^k` | that set has k members | | adding like `x^k` terms | tallying every distinct k-member set | | the coefficient of `x^k` | the number of k-member sets, C(n, k) | That is the whole argument, and it is worth noticing what it does **not** use. It never evaluates x. It never invokes a factorial expression. It never needs the coefficients computed in advance - the counting interpretation comes first, and any closed form for C(n, k) is a separate matter. ## Order does not enter The decision is made **per engineer**, not per position. There is no first pick or second pick, because each factor is consulted exactly once and independently. That is why the coefficient counts sets rather than sequences: two orderings of the same two engineers are not two different decision strings, they are the same string read twice. A candidate who reaches for an ordered count here has silently replaced the per-factor decision with a sequence of draws, which is a different process and a different number. ## Substituting values, and what each substitution says Because the identity holds as polynomials, it holds for every value of x, and each substitution turns the counting statement into an arithmetic one: 1. **x = 1** collapses every monomial to 1, so the sum of all the coefficients equals 2^n - the number of decision strings you started with. 2. **x = -1** makes the terms alternate, and the total is 0 for every n greater than 0, which says the k-member sets with k even and those with k odd are equally numerous. 3. **Two free symbols** generalise it: in `(a + b)^n`, picking `a` from k factors and `b` from the rest gives the term C(n, k)a^k b^(n-k), and the coefficient still counts which k factors contributed `a`. The third form is the binomial theorem in its usual dress, and the reading is unchanged: **a binomial coefficient in an expansion is always answering the question which factors contributed this symbol**. ## Why an interviewer asks this The payoff is not the polynomial. It is that a count you can only produce as a formula is a count you cannot check, while a count you can produce as a decision process is one you can argue about in a design review. An engineer who can say what x^k is recording can also tell you what happens when the model changes - engineers who must be included, pools that cannot mix, sizes that are capped - because those constraints change which decision strings survive, and the surviving strings are still visible in the expansion. - The exponent tracks **size**; the coefficient tracks **how many sets of that size exist**. - The 2^n pre-collection terms are the **decision strings**, not the answer. - Every substitution for x is a **different question asked of the same shelf of facts**. - The argument is stable under relabelling: nothing depends on which engineer got which factor.

  • Why does the coefficient of x^k equal the coefficient of x^(n-k) in the same expansion?
    Because naming the k engineers who contributed `x` is the same act as naming the n-k engineers who contributed `1`. The two descriptions are two readings of one decision string, and the correspondence is one-to-one in both directions, so the tallies cannot differ. That is the symmetry identity C(n, k) = C(n, n-k), read as choose who is excluded.
  • What does substituting x = -1 tell you about reviewer sets?
    Every term picks up a sign matching the parity of its size, and the total is (1 - 1)^n = 0 for any n above 0. So the number of even-sized reviewer sets equals the number of odd-sized ones on any non-empty roster. It is a counting statement obtained purely by evaluating an identity you already believe.
  • How does the same argument give the coefficient in (a + b)^n?
    Each factor now offers `a` or `b` instead of `x` or `1`. A decision string that takes `a` from k factors multiplies to a^k b^(n-k), and the number of strings producing that monomial is the number of ways to choose which k factors gave `a`. So the term is C(n, k)a^k b^(n-k), and the coefficient still counts a choice of factors.

saying these in an interview costs you the question

  • Thinks each x^k term comes from one factor rather than from k factors
  • Says the coefficient counts ordered picks, so it should be n!/(n-k)!
  • Believes the coefficients must be computed before they can be interpreted
  • Assumes every expanded term is distinct, so all coefficients equal 1
  • Insists x needs a numeric value before the expansion means anything
open as a page

On an n-engineer roster, why does summing the number of possible reviewer sets of every size 0 through n give exactly 2^n?

level: middleimportance: must knowfreq 50%

basics

~20 s

Both totals count one collection: every reviewer set the roster can produce. Grouping that collection by size and adding the groups gives the sum of binomial coefficients; building a set by deciding in or out per engineer gives 2^n. One collection, two tallies, so they are equal.

open as a page

A nightly job must count records matching none of k taint filters - why must the correction terms alternate in sign?

level: middleimportance: must knowfreq 66%

basics

~20 s

Subtracting each filter's matches over-corrects records caught by several filters, so pairwise overlaps are added back, triples removed again, and so on. The alternating signs make every record matching at least one filter cancel to exactly zero.

open as a page

Using inclusion-exclusion, how do you count the IDs from 1 to 1000 divisible by none of 2, 3 and 5?

level: middleimportance: must knowfreq 50%

basics

~10 s

Subtract from 1000 the multiples of 2, 3 and 5, add back the multiples of 6, 10 and 15, then subtract the multiples of 30. That is 1000 - 734 = 266 surviving IDs.

open as a page

In a length-n maintenance schedule where no two maintenance slots may be adjacent, why does the count satisfy f(n)=f(n-1)+f(n-2)?

level: middleimportance: must knowfreq 60%

basics

~10 s

Split on the last slot. Idle leaves any valid (n-1)-schedule; maintenance forces the previous slot idle, leaving any valid (n-2)-schedule. The two cases are disjoint and exhaustive, so their counts add.

open as a page

When a load balancer hashes requests across 16 shards, what must hold before calling each shard's share exactly 1/16?

level: middleimportance: must knowfreq 58%

basics

~20 s

Dividing favourable outcomes by total outcomes is valid only when the outcomes are equally likely, mutually exclusive and exhaustive. A 1/16 share assumes the hash spreads the actual traffic uniformly, each request lands on exactly one shard, and the shard count is fixed.

open as a page

What does the union bound give for 200 shards each 0.1% likely to overflow this hour?

level: middleimportance: must knowfreq 52%

basics

~20 s

At most 20%. The union bound says the chance that any bad event happens is no more than the sum of their individual chances, so 200 times 0.001 gives 0.2. It is an upper bound, and it needs no independence assumption.

open as a page

When counting the jobs a CI build matrix expands to, how do you decide between multiplying axis sizes and adding case counts?

level: middleimportance: must knowfreq 66%

basics

~20 s

Multiply when a job is built by making one independent choice on each axis, so the options on one axis never depend on another. Add when the jobs split into cases that no single job can belong to twice.

open as a page

Your count of a build matrix's jobs exceeds what the pipeline actually schedules, so how do you locate the double count?

level: seniorimportance: must knowfreq 52%

basics

~20 s

Find the object your enumeration reaches twice. The usual causes are cases that are not disjoint, an order imposed on something that has none, and a symmetry never divided out. Give each job one canonical name, count names, and compare.

open as a page

Why is counting a build matrix's policy-excluded combinations and subtracting often easier than counting the allowed ones directly?

level: middleimportance: should knowfreq 44%

basics

~20 s

The excluded side is usually the smaller and simpler one to describe, and it is often a clean product while the allowed side is not. Complementary counting is exact: full universe minus excluded, provided each excluded item is counted once.

open as a page

Why does C(m+p, k) equal the sum over j of C(m, j) times C(p, k-j) when a roster splits into m platform engineers and p service owners?

level: seniorimportance: should knowfreq 33%

basics

~20 s

Both sides count k-member reviewer sets on the combined roster. The right side splits that collection by how many members j come from the platform pool, then multiplies the choices within each pool. The split is a partition, so adding the cases reproduces the left side.

open as a page

In a rebalance where no shard may stay on its former host, what fraction of all n! reassignments qualify?

level: seniorimportance: should knowfreq 34%

basics

~20 s

Roughly 37 percent - about 1/e - and from n = 5 onward the fraction barely moves as n grows. These no-fixed-point arrangements are derangements, counted by an alternating sum over the shards that could have stayed put.

open as a page

Why does the number of balanced delimiter sequences with n pairs follow a convolution recurrence rather than a linear one?

level: seniorimportance: should knowfreq 36%

basics

~20 s

Because the split point varies. The closer matching the first opener can fall anywhere, cutting the sequence into an inside part and a remainder, so C(n) is a sum of products C(i)*C(n-1-i) — products of unknowns, not a fixed-length weighted sum.

open as a page

For the counting recurrence f(n)=f(n-1)+f(n-2), what does solving the characteristic equation r^2=r+1 give you that iteration does not?

level: seniorimportance: should knowfreq 44%

basics

~10 s

A closed form and a growth rate. Guessing f(n)=r^n turns the recurrence into r^2=r+1, whose roots (1+sqrt5)/2 and (1-sqrt5)/2 combine as Ar1^n + Br2^n; the larger root, about 1.618, is the per-step growth factor.

open as a page

How do you get the expected number of empty shards when n keys are hashed uniformly across n shards?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Attach one indicator per shard - worth 1 when that shard stays empty - and add the indicators' probabilities. Each shard is empty with probability (1 - 1/n)^n, so the expected count is n times that, about 0.37n for large n.

open as a page

Why does a random identifier space of n values tolerate only about sqrt(n) identifiers before a collision is likely?

level: seniorimportance: should knowfreq 62%

basics

~20 s

Because collisions happen between pairs, and k identifiers make about k^2/2 pairs, each colliding with probability 1/n. The summed risk reaches order 1 near k = sqrt(2n), so the tolerable count grows only as the square root of the space.

open as a page

What does row n of Pascal's triangle tell a lead choosing k for a k-of-n approval rule?

level: principalimportance: should knowfreq 24%

basics

~20 s

The row lists how many distinct k-member approver groups each choice of k admits. It is mirror-symmetric, rises to a peak near k = n/2, and totals 2^n. It sizes the space of approving groups - it says nothing about how strict or how satisfiable the rule is.

open as a page

With 20 overlapping taint filters the avoid-all sum needs 2^20 terms - how do you decide what to compute instead?

level: principalimportance: should knowfreq 30%

basics

~20 s

Decide by what you can touch. With the raw records in reach, one pass evaluating a compound predicate costs about n times k and is exact; the signed sum is for when only aggregate set sizes are available, and at twenty filters its million terms mean a million measurements.

open as a page

Two proposed maintenance rules give valid-schedule counts growing like 1.62^n and 2^n — what should that difference change about the design?

level: principalimportance: should knowfreq 28%

basics

~20 s

Less than it first appears. Both counts are exponential, so neither space can be enumerated at realistic n; the tighter rule buys a growing factor — roughly 4,000 times fewer schedules at n=40 — which helps pruning and reach, not feasibility in kind.

open as a page

As a build matrix accumulates exclusions, when should you model it as a sum of disjoint job families rather than one product with exceptions?

level: principalimportance: should knowfreq 33%

basics

~20 s

Switch when the exceptions stop being a short, independent list. One product minus exceptions stays compact while exclusions are few; once exclusions interact, a sum of disjoint families keeps each part a plain product and makes the total verifiable.

open as a page

Why does the running total C(2,2) + C(3,2) + ... + C(n,2) collapse to the single value C(n+1, 3)?

level: seniorimportance: nice to knowfreq 20%

basics

~20 s

Both sides count the 3-member panels formable from n+1 engineers ranked by seniority. Grouping those panels by their most senior member, a panel topped by rank m has its other two chosen from the m-1 below, and summing over m gives exactly that running total.

open as a page

How do you count the ways to place n distinct records into k named buckets with no bucket left empty?

level: seniorimportance: nice to knowfreq 24%

basics

~20 s

Take all k^n placements and remove those that miss at least one bucket by an alternating sum: sum over j of (-1)^j C(k,j) (k-j)^n. For 5 records into 3 buckets that is 243 - 96 + 3 = 150.

open as a page

When a counting recurrence's characteristic polynomial has a repeated root r, why is A*r^n + B*r^n not a general solution?

level: seniorimportance: nice to knowfreq 24%

basics

~20 s

Because it collapses: Ar^n + Br^n is (A+B)r^n, one free constant where a second-order recurrence needs two, so it cannot match two independent starting values. The missing second solution is nr^n, giving (A + B*n)*r^n.

open as a page

In a token ring of n services where only who-follows-whom matters, why does counting every ordering overcount distinct rings n-fold?

level: seniorimportance: nice to knowfreq 28%

basics

~20 s

A ring has no first position, so each ring is written down once for every choice of which service you list first. With n distinct services, those n rotations are all different orderings but the same ring, so the ordering count is n times too large.

open as a page

How do you decide what collision probability a randomly generated identifier scheme may carry across a service's lifetime?

level: principalimportance: nice to knowfreq 26%

basics

~20 s

Set the budget from what a duplicate would actually cost, not from taste. Compare it with failures already tolerated, apply it to lifetime volume over the scope where uniqueness must hold, then invert the collision bound to get the required width.

open as a page