diff --git a/Level 1/Week 06/Queue/2073. Time Needed to Buy Tickets/code.cpp b/Level 1/Week 06/Queue/2073. Time Needed to Buy Tickets/code.cpp index 2e0f3e1..a950221 100644 --- a/Level 1/Week 06/Queue/2073. Time Needed to Buy Tickets/code.cpp +++ b/Level 1/Week 06/Queue/2073. Time Needed to Buy Tickets/code.cpp @@ -1,50 +1,154 @@ -#include -#include -using namespace std; - -// 🧠 Approach: -// This problem simulates a queue of people buying tickets with time tracking. -// 1. Use a queue to store pairs of (position, remaining_tickets) for each person. -// 2. Track time as each person takes 1 second to buy a ticket. -// 3. When a person buys a ticket, decrement their remaining tickets. -// 4. If they still have tickets, they go to the back of the queue. -// 5. If they're done (0 tickets), they leave the queue. -// 6. Continue until the person at position k finishes buying all their tickets. -// 7. The key insight is to track the target person and count time for each ticket purchase. - -// ✅ Time Complexity: O(tickets[k] * n), where n is the number of people -// ✅ Space Complexity: O(n), for the queue +/* +There are 3 approaches, but we will solve it using a queue because in this repo we are studying queues + +Understanding +------------- +Problem: +- Given an array 'tickets' where tickets[i] = number of tickets the i-th person wants. +- Index 'k' = target person. +- Each person buys 1 ticket per second, and after buying 1 ticket, goes back to the + end of the line if they have more tickets. +- Goal: Find total time (seconds) for person at index 'k' to finish buying all tickets. + +Observations: +1. Each person contributes to the total time depending on their position relative to 'k'. +2. Target person's total time = their own tickets + contributions from others. +--- + +SOLUTION 1: Formula-based (O(n) time, O(1) space) +-------------------------------------------------- +approch: +- Identify target person at index k with tickets[k] tickets. +- Total time = target person's own tickets + contribution of all other people. +- Contribution rules: + 1. If i <= k → person i will be in line until target finishes last ticket + → contribution = min(tickets[i], tickets[k]) + 2. If i > k → person i may not reach the last round after target finishes + → contribution = min(tickets[i], tickets[k]-1) +- Sum all contributions → total time for target to finish buying tickets. +- This avoids simulating the entire queue and gives O(n) time. + +Time Complexity: O(n) → single pass over tickets array. +Space Complexity: O(1) → only variables used (result, loop counter). + +*/ class Solution { public: int timeRequiredToBuy(vector& tickets, int k) { - queue> queue; // (position, remaining_tickets) - - // Initialize queue with all people + int result=0; + for(int i=0;i 0 → push back to queue + 4. if remaining == 0 and person is target → return time +- This is a literal simulation of the queue buying process. + +Time Complexity: O(n * m) → worst case every person buys ticket in multiple rounds. +Space Complexity: O(n) → queue stores up to n people at a time. + +*/ +class Solution2 { +public: + int timeRequiredToBuy(vector& tickets, int k) { + + queue> q; + for (int i = 0; i < tickets.size(); i++) { - queue.push({i, tickets[i]}); + q.push({i, tickets[i]}); } - + int time = 0; - - while (!queue.empty()) { - auto [position, remaining] = queue.front(); - queue.pop(); - - time++; // 1 second to buy a ticket - - remaining--; // Buy one ticket - - if (remaining > 0) { - // Person still has tickets, goes to back of queue - queue.push({position, remaining}); - } else if (position == k) { - // Target person finished buying all tickets - break; + + while (!q.empty()) { + auto [pos, remain] = q.front(); + q.pop(); + remain--; + time++; + if (remain > 0) { + q.push({pos, remain}); } - // If person is done and not the target, they just leave + if(pos==k && remain == 0) + return time; } - return time; } -}; \ No newline at end of file +}; + +/* +--- + +SOLUTION 3: Circular Simulation / Direct Array Modification (O(n*m) time, O(1) space) +---------------------------------------------------------------------------------------- +approch: +- Use two variables: 'sec' = total seconds, 'i' = current person index. +- Loop until target person tickets[k] = 0: + 1. If tickets[i] > 0 → decrement tickets[i], increment sec + 2. Move to next person: i++ + - If i == tickets.size() → i = 0 (start new round) +- When tickets[k] = 0 → return sec. +- This simulates queue circularly **without extra memory**. + +Time Complexity: O(n * m) → worst case loop runs tickets[k] * n times. +Space Complexity: O(1) → only counters used, tickets array modified in-place. + +*/ +class Solution3 { +public: + int timeRequiredToBuy(vector& tickets, int k) { + int sec = 0; + int i = 0; + + while (tickets[k] != 0) { + if (tickets[i] > 0) { + tickets[i]--; + sec++; + } + i++; + if (i == tickets.size()) i = 0; // complete a round + } + return sec; + } +}; + +/* +--- +Time & Space Complexity: + +| Approach | Time Complexity | Space Complexity | +|----------------------------|----------------|---------------- | +| Formula-based | O(n) | O(1) | +| Queue simulation | O(n*m) | O(n) | +| Circular array simulation | O(n*m) | O(1) | + + +*/