Time Needed to Buy Tickets
Problem
Each step the first person buys one ticket then goes to the back unless done. Return the time (in steps) until person at index k buys all their tickets.
tickets = [2, 3, 2], k = 26def time_required_to_buy(tickets, k):
total = 0
for i, t in enumerate(tickets):
if i <= k:
total += min(t, tickets[k])
else:
total += min(t, tickets[k] - 1)
return total
function timeRequiredToBuy(tickets, k) {
let total = 0;
for (let i = 0; i < tickets.length; i++) {
if (i <= k) total += Math.min(tickets[i], tickets[k]);
else total += Math.min(tickets[i], tickets[k] - 1);
}
return total;
}
class Solution {
public int timeRequiredToBuy(int[] tickets, int k) {
int total = 0;
for (int i = 0; i < tickets.length; i++) {
if (i <= k) total += Math.min(tickets[i], tickets[k]);
else total += Math.min(tickets[i], tickets[k] - 1);
}
return total;
}
}
int timeRequiredToBuy(vector<int>& tickets, int k) {
int total = 0;
for (int i = 0; i < (int)tickets.size(); i++) {
if (i <= k) total += min(tickets[i], tickets[k]);
else total += min(tickets[i], tickets[k] - 1);
}
return total;
}
Explanation
You could literally simulate the line — buy a ticket, send the person to the back, repeat — but there is a much faster counting shortcut that needs just one pass and no queue at all.
The key insight is that person k stops the instant they buy their last ticket, after tickets[k] rounds. So we ask, for everyone else, how many tickets they manage to buy before that moment.
Anyone at or ahead of k (index i <= k) gets a turn in every one of those rounds, so they buy min(tickets[i], tickets[k]). Anyone behind k (index i > k) gets one fewer chance, because the line stops right when k finishes — so they buy min(tickets[i], tickets[k] - 1).
Each ticket bought is one unit of time, so we just add up all these contributions with total += ... and return the sum.
Example: tickets = [2, 3, 2], k = 2. Person 0 (ahead): min(2, 2) = 2. Person 1 (ahead): min(3, 2) = 2. Person 2 (k itself): min(2, 2) = 2. Total = 6, all in O(n).