Time Needed to Buy Tickets
Problem
i wants tickets[i] tickets.
Each second, the person at the front buys one ticket, then walks to the back of the
line if they still need more (otherwise they leave). Return how many seconds pass until the
person at index k has bought all of their tickets.tickets=[2,3,2], k=2Output6tickets=[5,1,1,1], k=0Output81 ≤ n ≤ 100 · 1 ≤ tickets[i] ≤ 100 · 0 ≤ k < n
Try it yourself
class Solution {
public int timeRequiredToBuy(int[] tickets, int k) {
}
}
k finishes in round tickets[k]. Everyone ahead of
k buys at most tickets[k] tickets by then, everyone behind at most
tickets[k] - 1 — so the answer is a single sum of mins.Instinct Arrival order matters, or you need the max/min of a moving window - reach for a FIFO queue, or a deque of indices kept in sorted order.
Memory hack Old ones leave by the front door, weak ones get bounced out the back - so whoever stands at the front is always the champion.
Open the Queue & Monotonic Deque guide →Approaches
Brute ForceSimulate the Queue
O(n · max(tickets))Space O(n)Model the line literally: a queue of person indices. Each second, poll the
front, decrement their count, and re-enqueue them if they still need tickets. Stop
the moment person k reaches zero.
public int timeRequiredToBuy(int[] tickets, int k) { int[] left = tickets.clone(); Deque<Integer> line = new ArrayDeque<>(); for (int i = 0; i < left.length; i++) line.offerLast(i); int time = 0; while (true) { int person = line.pollFirst(); left[person]--; time++; if (left[person] == 0) { if (person == k) return time; } else { line.offerLast(person); // back of the line } } }
Mirrors the statement exactly, but runs one step per ticket sold.
OptimalOne-Pass Counting
O(n)Space O(1)Count each person's purchases up to the moment k finishes. People at
index ≤ k get a turn in round tickets[k] before
k is done, so they buy min(tickets[i], tickets[k]); people
behind k miss that last round and buy
min(tickets[i], tickets[k] - 1).
public int timeRequiredToBuy(int[] tickets, int k) { int time = 0; for (int i = 0; i < tickets.length; i++) { // people behind k do not get a turn in k's final round int cap = i <= k ? tickets[k] : tickets[k] - 1; time += Math.min(tickets[i], cap); } return time; }
Dry runtickets=[2,3,2], k=2
- start5k111cap ahead=5, behind=4
- i=05i k111+min(5,5)=5
- i=151i11+min(1,4)=1 → 6
- i=2511i1+min(1,4)=1 → 7
- i=35111i+min(1,4)=1 → 8 ✔
Single pass, no simulation — the expected answer.
k's last round, only people in front
of k (and k) get served.At a glance
| Level | Approach | Time | Space |
|---|---|---|---|
| Brute Force | Simulate the Queue | O(n · max(tickets)) | O(n) |
| Optimal | One-Pass Counting | O(n) | O(1) |
- Using
tickets[k]as the cap for people behindk— off by one per person. - Mutating the caller's
ticketsarray in the simulation. - Stopping the simulation when anyone hits zero instead of person
k.
- Start with the queue simulation — it is quick and proves you read the rules.
- Then reason in rounds to derive the min-sum formula.
- Verify the formula on the
[5,1,1,1], k=0example.