AlgoMaster Logo

Queue Reconstruction by Height

mediumFrequencyUpdated September 21, 2026

Understanding the Problem

We have a shuffled list of people, and each person tells us two things: their height, and how many people who are at least as tall stand in front of them in the original queue. We need to figure out the original ordering.

The constraint that drives every solution is that k only counts people who are taller or equal, not shorter. A short person standing in front of a tall person does not change the tall person's k value. This asymmetry is what makes a greedy ordering possible.

Stated differently, a person of height 7 counts only other people of height 7 or more in front of them. People of height 4, 5, or 6 are irrelevant to that count. So if we fix the positions of all the tall people first, we can place shorter people afterward without changing any tall person's count.

Key Constraints

  • 1 <= people.length <= 2000: With n up to 2000, an O(n^2) approach runs in about 4 million operations and passes comfortably. An O(n log n) approach exists and is the focus of the final section.
  • 0 <= k_i < people.length: Every k is in range, and the problem guarantees a valid reconstruction exists, so we never have to detect an impossible input.
  • 0 <= h_i <= 10^6: Heights can be large. We only compare and sort them, so the magnitude never matters and there is no overflow risk.

Approach 1: Brute Force (Try All Permutations)

Intuition

Try every possible ordering of the people and check which one satisfies all the constraints. For each permutation, verify that every person has exactly k people taller or equal in front of them.

This is simple but impractical. With n people there are n! permutations, and for n = 10 that is already 3.6 million orderings, each needing O(n^2) to verify. For n = 2000 it is far beyond any time limit. We include it only to fix the validity check we are aiming for, then improve from there.

Algorithm

  1. Generate all permutations of the people array.
  2. For each permutation, check if it forms a valid queue:
    • For each person at position j, count how many people at positions 0 to j-1 have height >= this person's height.
    • If the count equals k for every person, this permutation is the answer.
  3. Return the valid permutation.

Visualization and Code

Loading animation...

The brute force ignores the structure in each person's k value. If we process people in the right order, k tells us directly where to place each one, with no search at all.

Approach 2: Greedy (Sort by Height Descending + Insert by k)

Intuition

A tall person's count depends only on taller-or-equal people. A person of height 7 with k = 1 needs exactly 1 person of height 7 or more in front of them, and shorter people in front do not change that count.

So we place the tallest people first. While the queue contains only tall people, each one's k value is exactly the index where it belongs, because everyone already placed is taller or equal.

When we later insert a shorter person at index k, every person already in the list is taller or equal, so the insertion puts exactly k taller-or-equal people in front of them. The insertion also does not change the count of anyone already placed, because those people are all taller or equal and do not count the newcomer.

The sort is by height descending, breaking ties by k ascending. The tie-break matters: among people of equal height, the one with the smaller k belongs further left. Placing it first, at the smaller index, leaves the equal-height person with the larger k to land to its right when inserted later, which is the order their k values require.

Algorithm

  1. Sort people by height in descending order. For people with the same height, sort by k in ascending order.
  2. Create an empty result list.
  3. Iterate through the sorted array. For each person [h, k], insert them at index k in the result list.
  4. Return the result list.

Visualization and Code

Loading animation...

The cost here is the insertion. Each insert at an arbitrary index shifts every element after it, which is O(n) per person and O(n^2) overall. The next approach removes the shifting by sorting the other direction and computing each final position with a data structure that answers "where is the k-th open slot" in logarithmic time.

Approach 3: Optimal (Sort by Height Ascending + Segment Tree for Empty Slots)

Intuition

Process the shortest people first. When we place the shortest person, everyone not yet placed is taller or equal, so that person's k value tells us they need k taller-or-equal people in front. Every remaining empty slot will eventually hold a taller-or-equal person, so the person belongs in the (k+1)th empty slot from the left: skip k empty slots, then take the next one.

The sort is by height ascending, breaking ties by k descending. Among people of equal height, the one with the larger k is placed first, into a later empty slot. When the equal-height person with the smaller k is placed afterward, it lands in an earlier empty slot, which is the correct relative order for two people of the same height.

A direct scan for the (k+1)th empty slot costs O(n) per person, giving O(n^2). The improvement is to answer "which index is the (k+1)th empty slot" in O(log n) with a segment tree over slot positions. Each leaf holds 1 if its slot is empty and 0 once filled, and each internal node stores the sum of its children, the number of empty slots in its range. To find the (k+1)th empty slot, descend from the root: if the left child has more than k empty slots the target is on the left, otherwise subtract the left child's count from k and go right. When we reach a leaf, that is the slot; set it to 0 and propagate the change upward.

Algorithm

  1. Sort people by height ascending. For the same height, sort by k descending.
  2. Build a segment tree over n leaves, each initialized to 1 (every slot starts empty). Internal nodes store the count of empty slots in their range.
  3. For each person [h, k] in sorted order:
    • Query the tree for the index of the (k+1)th empty slot (skip k empty slots from the left).
    • Place the person there and set that leaf to 0, updating ancestors.
  4. Return the result array.

Visualization and Code

Loading animation...