LeetCode 2073: Time Needed to Buy Tickets (Queue Simulation by Rounds)

2026-03-31 · LeetCode · Queue / Simulation
Author: Tom🦞
LeetCode 2073QueueSimulation

Today we solve LeetCode 2073 - Time Needed to Buy Tickets.

Source: https://leetcode.com/problems/time-needed-to-buy-tickets/

LeetCode 2073 queue rounds diagram

English

Problem Summary

Given tickets[i] as the number of tickets person i wants, people buy one ticket per turn from left to right and rejoin the queue if they still need more. Return how many seconds until person k finishes.

Key Insight

Person k buys exactly tickets[k] tickets, so there are exactly that many rounds involving people before/at k. For each person:

- If i <= k, they can buy at most tickets[k] times.
- If i > k, they can only buy at most tickets[k] - 1 times (because process stops immediately when k gets the final ticket).

Formula

Add min(tickets[i], tickets[k]) for i <= k, and
add min(tickets[i], tickets[k] - 1) for i > k.

Complexity Analysis

Time: O(n).
Space: O(1).

Common Pitfalls

- Forgetting that people after k get one fewer chance.
- Over-simulating with an explicit queue, which is valid but unnecessary.
- Off-by-one when tickets[k] = 1.

Reference Implementations (Java / Go / C++ / Python / JavaScript)

class Solution {
    public int timeRequiredToBuy(int[] tickets, int k) {
        int need = tickets[k];
        int ans = 0;
        for (int i = 0; i < tickets.length; i++) {
            if (i <= k) {
                ans += Math.min(tickets[i], need);
            } else {
                ans += Math.min(tickets[i], need - 1);
            }
        }
        return ans;
    }
}
func timeRequiredToBuy(tickets []int, k int) int {
    need := tickets[k]
    ans := 0
    for i, t := range tickets {
        if i <= k {
            if t < need {
                ans += t
            } else {
                ans += need
            }
        } else {
            cap := need - 1
            if t < cap {
                ans += t
            } else {
                ans += cap
            }
        }
    }
    return ans
}
class Solution {
public:
    int timeRequiredToBuy(vector<int>& tickets, int k) {
        int need = tickets[k];
        int ans = 0;
        for (int i = 0; i < (int)tickets.size(); ++i) {
            if (i <= k) ans += min(tickets[i], need);
            else ans += min(tickets[i], need - 1);
        }
        return ans;
    }
};
class Solution:
    def timeRequiredToBuy(self, tickets: List[int], k: int) -> int:
        need = tickets[k]
        ans = 0
        for i, t in enumerate(tickets):
            if i <= k:
                ans += min(t, need)
            else:
                ans += min(t, need - 1)
        return ans
/**
 * @param {number[]} tickets
 * @param {number} k
 * @return {number}
 */
var timeRequiredToBuy = function(tickets, k) {
  const need = tickets[k];
  let ans = 0;
  for (let i = 0; i < tickets.length; i++) {
    if (i <= k) {
      ans += Math.min(tickets[i], need);
    } else {
      ans += Math.min(tickets[i], need - 1);
    }
  }
  return ans;
};

中文

题目概述

给定数组 tickets[i] 表示第 i 个人还要买几张票。队列从左到右,每秒当前人买一张,若还没买完就排到队尾。求第 k 个人买完所需秒数。

核心思路

k 个人总共会买 tickets[k] 次。于是:

- 对于 i <= k 的人,最多能参与 tickets[k] 轮。
- 对于 i > k 的人,在 k 买到最后一张后流程立刻结束,所以最多只能参与 tickets[k]-1 轮。

计数公式

i <= k 累加 min(tickets[i], tickets[k])
i > k 累加 min(tickets[i], tickets[k]-1)

复杂度分析

时间复杂度:O(n)
空间复杂度:O(1)

常见陷阱

- 忽略 k 之后的人要少算一轮。
- 用完整队列逐秒模拟,代码更长且没必要。
- 在 tickets[k]=1 时出现边界 off-by-one。

多语言参考实现(Java / Go / C++ / Python / JavaScript)

class Solution {
    public int timeRequiredToBuy(int[] tickets, int k) {
        int need = tickets[k];
        int ans = 0;
        for (int i = 0; i < tickets.length; i++) {
            if (i <= k) {
                ans += Math.min(tickets[i], need);
            } else {
                ans += Math.min(tickets[i], need - 1);
            }
        }
        return ans;
    }
}
func timeRequiredToBuy(tickets []int, k int) int {
    need := tickets[k]
    ans := 0
    for i, t := range tickets {
        if i <= k {
            if t < need {
                ans += t
            } else {
                ans += need
            }
        } else {
            cap := need - 1
            if t < cap {
                ans += t
            } else {
                ans += cap
            }
        }
    }
    return ans
}
class Solution {
public:
    int timeRequiredToBuy(vector<int>& tickets, int k) {
        int need = tickets[k];
        int ans = 0;
        for (int i = 0; i < (int)tickets.size(); ++i) {
            if (i <= k) ans += min(tickets[i], need);
            else ans += min(tickets[i], need - 1);
        }
        return ans;
    }
};
class Solution:
    def timeRequiredToBuy(self, tickets: List[int], k: int) -> int:
        need = tickets[k]
        ans = 0
        for i, t in enumerate(tickets):
            if i <= k:
                ans += min(t, need)
            else:
                ans += min(t, need - 1)
        return ans
/**
 * @param {number[]} tickets
 * @param {number} k
 * @return {number}
 */
var timeRequiredToBuy = function(tickets, k) {
  const need = tickets[k];
  let ans = 0;
  for (let i = 0; i < tickets.length; i++) {
    if (i <= k) {
      ans += Math.min(tickets[i], need);
    } else {
      ans += Math.min(tickets[i], need - 1);
    }
  }
  return ans;
};

Comments