Skip to content

Parameter Fixing (Beginner)

Most algorithm problems have multiple moving parts. Two numbers that need to relate. An index and a value. A node and a path. When everything moves at once, the problem feels impossible.

The trick: stop one thing from moving. Fix one variable, and suddenly the other variables are constrained — sometimes completely determined.

This page teaches the core idea with simple examples. No trees, no graphs, no advanced math. Just arrays and the fixing mindset.


The Idea in 30 Seconds

You have a problem with two unknowns, \(x\) and \(y\). Trying all pairs is \(O(N^2)\). But if you fix \(x\), maybe \(y\) is forced — or at least narrowed down.

That's it. That's the whole technique. Fix one thing, figure out the rest.


Example 1: Two Sum

Given an array and a target sum, find two numbers that add up to the target.

The brute force: Try every pair \((i, j)\). That's \(O(N^2)\).

The fixing approach: Walk through the array. At each element \(x\), ask: "what value \(y\) do I need?" The answer: \(y = \text{target} - x\). That's forced — there's only one possible \(y\).

Now check if \(y\) exists (using a hash set of values seen so far). If it does, you're done. If not, add \(x\) to the set and move on.

Array: [2, 7, 11, 15], Target: 9

Step 1: x = 2, need y = 7. Seen = {}. Not found. Add 2.
Step 2: x = 7, need y = 2. Seen = {2}. Found! Answer: (2, 7).

\(O(N)\) time. One pass. The key was fixing \(x\) and deducing \(y\).


Example 2: Count Good Pairs

Given an array, count the number of pairs \((i, j)\) where \(i < j\) and \(A[i] = A[j]\).

The brute force: Check every pair. \(O(N^2)\).

The fixing approach: Fix the right element \(j\). The question becomes: "how many previous elements equal \(A[j]\)?" Keep a count of how many times each value has appeared.

Array: [1, 2, 3, 1, 1, 3]

j=0: A[j]=1. Count of 1s before: 0. Pairs: 0. Counts: {1:1}
j=1: A[j]=2. Count of 2s before: 0. Pairs: 0. Counts: {1:1, 2:1}
j=2: A[j]=3. Count of 3s before: 0. Pairs: 0. Counts: {1:1, 2:1, 3:1}
j=3: A[j]=1. Count of 1s before: 1. Pairs: 1. Counts: {1:2, 2:1, 3:1}
j=4: A[j]=1. Count of 1s before: 2. Pairs: 3. Counts: {1:3, 2:1, 3:1}
j=5: A[j]=3. Count of 3s before: 1. Pairs: 4. Counts: {1:3, 2:1, 3:2}

Total: 4 pairs. \(O(N)\) time.

The pattern: fix the current element, use a hash map to quickly answer "what came before that matches?"


Example 3: Subarray Sum Equals K

Count the number of contiguous subarrays that sum to \(K\).

This is harder, but the same idea works.

A subarray from index \(j\) to \(i\) has sum \(= P[i] - P[j]\), where \(P\) is the prefix sum array. You want \(P[i] - P[j] = K\), which means \(P[j] = P[i] - K\).

Fix \(i\). The question becomes: "how many previous prefix sums equal \(P[i] - K\)?" That's the same hash map pattern.

Array: [1, 1, 1], K = 2
Prefix sums: [0, 1, 2, 3]

i=0: P=0. Need P[j] = 0-2 = -2. Count: 0. Store {0:1}
i=1: P=1. Need P[j] = 1-2 = -1. Count: 0. Store {0:1, 1:1}
i=2: P=2. Need P[j] = 2-2 = 0. Count: 1. Store {0:1, 1:1, 2:1}
i=3: P=3. Need P[j] = 3-2 = 1. Count: 1. Store {0:1, 1:1, 2:1, 3:1}

Total: 2 subarrays ([1,1] starting at index 0, and [1,1] starting at index 1). \(O(N)\) time.


The Pattern

Every example above follows the same structure:

  1. Pick a variable to fix. Usually the current element or the right endpoint.
  2. Ask: what does the other variable need to be? Derive it from the problem's equation.
  3. Look it up. Use a hash map, a set, or a sorted structure to check if that value exists.
  4. Update your bookkeeping. Add the current element's information for future lookups.

This pattern solves dozens of problems:

Problem Fix Deduce Lookup
Two Sum current element \(x\) \(y = \text{target} - x\) hash set
Good Pairs current element how many equal values before? hash map count
Subarray Sum = K current prefix sum what prefix sum do I need? hash map count
Two Sum (sorted) left pointer right pointer moves inward two pointers

The Four Questions

When you see a new problem, ask yourself:

  1. What are the moving parts? List every variable, index, or quantity.
  2. Which one should I fix? Usually the one that simplifies things most.
  3. If I fix it, what's forced? Can I compute the other variables directly?
  4. How do I look up the forced value quickly? Hash map? Binary search? Two pointers?

If fixing one variable gives you an \(O(1)\) or \(O(\log N)\) lookup for the rest, you've likely found the solution.


Practice Problems

Try these in order. Each one follows the fix-and-deduce pattern.

1. Two Sum (LC 1)

Fix each element. The complement is target - x. Use a hash map.

2. Number of Good Pairs (LC 1512)

Fix the right element. Count how many equal values appeared before it. Hash map of counts.

3. Subarray Sum Equals K (LC 560)

Prefix sum trick. Fix the right endpoint. Look up how many prefix sums equal P[i] - K.

4. Contains Duplicate II (LC 219)

Fix the current element. Check if the same value appeared within the last \(K\) indices. Use a hash map storing the most recent index of each value.

5. Count Number of Bad Pairs (LC 2364)

A pair is "bad" if \(j - i \ne A[j] - A[i]\). Rearrange: \(A[j] - j \ne A[i] - i\). Fix \(j\), compute \(A[j] - j\). Count how many previous elements have the same transformed value — those are the good pairs. Bad pairs = total pairs minus good pairs.


Ready for more? The full versions cover fixing on trees, graphs, absolute value tricks, and 35 practice problems: