There are n visitors standing in a queue. Each visitor prefers either pass type 0 or pass type 1. There are n passes placed in a stack, where passes[0] represents the pass on the top.
The process works as follows:
- If the visitor at the front of the queue prefers the pass on top of the stack, they take it and leave the queue.
- Otherwise, the visitor moves to the end of the queue.
- The process continues until no visitor in the queue prefers the pass currently on top of the stack.
Given two arrays visitors[] and passes[], return the number of visitors who are unable to get a pass.
Examples:
Input: visitors[] = [1, 0, 1] passes[] = [0, 1, 1]
Output: 0
Explanation: The first visitors prefers 1 while the top pass is 0, so they move to the end of the queue. The next visitors takes pass 0. The remaining visitors then take the remaining passes. Hence, all visitors receive a pass.
Input: visitors[] = [1, 0, 0, 1] passes[] = [0, 0, 0, 1]
Output: 2
Explanation: After two visitors take the first two passes, only visitors preferring 1 remain while the top pass is 0. Since no one wants the top pass, the process stops and 2 visitors remain without a pass.
Table of Content
[Naive Approach] Queue Simulation - O(n ^ 2) Time and O(n) Space
The idea is to simulate the given process using a queue. If the visitor at the front prefers the pass on top, they take it and leave the queue. Otherwise, they move to the end of the queue. If every visitor gets moved once without taking the current pass, no one wants that pass, so the remaining visitors cannot get a pass.
Working of Approach:
- Store all visitors in a queue and process the passes from the top of the stack one by one.
- If the visitor at the front prefers the current pass, they take it and leave the queue; otherwise, move them to the back of the queue.
- Keep track of how many consecutive visitors are moved without taking the current pass using skip.
- If skip becomes equal to the current queue size, no visitor wants the top pass, so stop the process and return the number of visitors left in the queue.
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int countVisitors(vector<int> &visitors, vector<int> &passes)
{
queue<int> q;
// Push all visitors into the queue.
for (int x : visitors)
q.push(x);
int idx = 0, skip = 0;
// Simulate the process.
while (!q.empty())
{
// Front visitor takes the current pass.
if (q.front() == passes[idx])
{
q.pop();
idx++;
skip = 0;
}
else
{
// Move the visitor to the end of the queue.
q.push(q.front());
q.pop();
skip++;
// No visitor wants the current pass.
if (skip == q.size())
break;
}
}
return q.size();
}
int main()
{
vector<int> visitors = {1, 0, 0, 1};
vector<int> passes = {0, 0, 0, 1};
cout << countVisitors(visitors, passes);
return 0;
}
import java.util.LinkedList;
import java.util.Queue;
class GFG {
static int countVisitors(int[] visitors, int[] passes)
{
Queue<Integer> q = new LinkedList<>();
// Push all visitors into the queue.
for (int x : visitors)
q.offer(x);
int idx = 0, skip = 0;
// Simulate the process.
while (!q.isEmpty()) {
// Front visitor takes the current pass.
if (q.peek() == passes[idx]) {
q.poll();
idx++;
skip = 0;
}
else {
// Move the visitor to the end of the queue.
q.offer(q.poll());
skip++;
// No visitor wants the current pass.
if (skip == q.size())
break;
}
}
return q.size();
}
public static void main(String[] args)
{
int[] visitors = { 1, 0, 0, 1 };
int[] passes = { 0, 0, 0, 1 };
System.out.println(countVisitors(visitors, passes));
}
}
from collections import deque
def countVisitors(visitors, passes):
q = deque()
# Push all visitors into the queue.
for x in visitors:
q.append(x)
idx = 0
skip = 0
# Simulate the process.
while q:
# Front visitor takes the current pass.
if q[0] == passes[idx]:
q.popleft()
idx += 1
skip = 0
else:
# Move the visitor to the end of the queue.
q.append(q.popleft())
skip += 1
# No visitor wants the current pass.
if skip == len(q):
break
return len(q)
if __name__ == "__main__":
visitors = [1, 0, 0, 1]
passes = [0, 0, 0, 1]
print(countVisitors(visitors, passes))
using System;
using System.Collections.Generic;
class GFG {
static int countVisitors(int[] visitors, int[] passes)
{
Queue<int> q = new Queue<int>();
// Push all visitors into the queue.
foreach(int x in visitors) q.Enqueue(x);
int idx = 0, skip = 0;
// Simulate the process.
while (q.Count > 0) {
// Front visitor takes the current pass.
if (q.Peek() == passes[idx]) {
q.Dequeue();
idx++;
skip = 0;
}
else {
// Move the visitor to the end of the queue.
q.Enqueue(q.Dequeue());
skip++;
// No visitor wants the current pass.
if (skip == q.Count)
break;
}
}
return q.Count;
}
static void Main()
{
int[] visitors = { 1, 0, 0, 1 };
int[] passes = { 0, 0, 0, 1 };
Console.Write(countVisitors(visitors, passes));
}
}
function countVisitors(visitors, passes)
{
let q = [];
// Push all visitors into the queue.
for (let x of visitors)
q.push(x);
let idx = 0, skip = 0;
// Simulate the process.
while (q.length > 0) {
// Front visitor takes the current pass.
if (q[0] === passes[idx]) {
q.shift();
idx++;
skip = 0;
}
else {
// Move the visitor to the end of the queue.
q.push(q.shift());
skip++;
// No visitor wants the current pass.
if (skip === q.length)
break;
}
}
return q.length;
}
// Driver code
let visitors = [ 1, 0, 0, 1 ];
let passes = [ 0, 0, 0, 1 ];
console.log(countVisitors(visitors, passes));
Output
2
[Expected Approach] Counting Preferences - O(n) Time and O(1) Space
The idea is to count the number of visitors preferring each pass type. Then process the passes from top to bottom. If a visitor is available for the current pass type, decrease its count. Otherwise, no visitor wants the current top pass, so the remaining visitors cannot get a pass.
Working of Approach:
- Count the number of visitors preferring pass type 0 and pass type 1.
- Traverse the passes from top to bottom and check whether a visitor is available for the current pass type.
- If a matching visitor exists, decrease its count as that visitor takes the pass.
- Otherwise, no visitor wants the current top pass, so stop the process and return the number of remaining passes (n - i) as the number of visitors without a pass.
Let us understand with an example:
Input: visitors[] = [1, 0, 0, 1] passes[] = [0, 0, 0, 1]
- Initially, s0 = 2 and s1 = 2 as there are two visitors preferring each pass type.
- The first two passes are 0, so two visitors preferring 0 take them. Now, s0 = 0 and s1 = 2.
- The next pass is also 0, but no visitor preferring 0 is left (s0 = 0).
- The process stops since no visitor wants the current top pass.
- The remaining passes are 2 (n - i = 4 - 2 = 2), so the answer is 2.
#include <iostream>
#include <vector>
using namespace std;
int countVisitors(vector<int> &visitors, vector<int> &passes)
{
int s0 = 0, s1 = 0;
// Count visitors preferring each pass type.
for (int x : visitors)
{
if (x == 0)
s0++;
else
s1++;
}
int n = passes.size();
int res = 0;
// Process passes from top to bottom.
for (int i = 0; i < n; i++)
{
// A visitor takes the current pass.
if (passes[i] == 0 && s0 > 0)
s0--;
else if (passes[i] == 1 && s1 > 0)
s1--;
// No visitor wants the current pass.
else
{
res = n - i;
break;
}
}
return res;
}
int main()
{
vector<int> visitors = {1, 0, 0, 1};
vector<int> passes = {0, 0, 0, 1};
cout << countVisitors(visitors, passes);
return 0;
}
import java.util.*;
class GFG {
static int countVisitors(int[] visitors, int[] passes)
{
int s0 = 0, s1 = 0;
// Count visitors preferring each pass type.
for (int x : visitors) {
if (x == 0)
s0++;
else
s1++;
}
int n = passes.length;
int res = 0;
// Process passes from top to bottom.
for (int i = 0; i < n; i++) {
// A visitor takes the current pass.
if (passes[i] == 0 && s0 > 0)
s0--;
else if (passes[i] == 1 && s1 > 0)
s1--;
// No visitor wants the current pass.
else {
res = n - i;
break;
}
}
return res;
}
public static void main(String[] args)
{
int[] visitors = { 1, 0, 0, 1 };
int[] passes = { 0, 0, 0, 1 };
System.out.println(countVisitors(visitors, passes));
}
}
def countVisitors(visitors, passes):
s0 = 0
s1 = 0
# Count visitors preferring each pass type.
for x in visitors:
if x == 0:
s0 += 1
else:
s1 += 1
n = len(passes)
res = 0
# Process passes from top to bottom.
for i in range(n):
# A visitor takes the current pass.
if passes[i] == 0 and s0 > 0:
s0 -= 1
elif passes[i] == 1 and s1 > 0:
s1 -= 1
# No visitor wants the current pass.
else:
res = n - i
break
return res
if __name__ == "__main__":
visitors = [1, 0, 0, 1]
passes = [0, 0, 0, 1]
print(countVisitors(visitors, passes))
using System;
class GFG {
static int countVisitors(int[] visitors, int[] passes)
{
int s0 = 0, s1 = 0;
// Count visitors preferring each pass type.
foreach(int x in visitors)
{
if (x == 0)
s0++;
else
s1++;
}
int n = passes.Length;
int res = 0;
// Process passes from top to bottom.
for (int i = 0; i < n; i++) {
// A visitor takes the current pass.
if (passes[i] == 0 && s0 > 0)
s0--;
else if (passes[i] == 1 && s1 > 0)
s1--;
// No visitor wants the current pass.
else {
res = n - i;
break;
}
}
return res;
}
static void Main()
{
int[] visitors = { 1, 0, 0, 1 };
int[] passes = { 0, 0, 0, 1 };
Console.Write(countVisitors(visitors, passes));
}
}
function countVisitors(visitors, passes)
{
let s0 = 0, s1 = 0;
// Count visitors preferring each pass type.
for (let x of visitors) {
if (x === 0)
s0++;
else
s1++;
}
let n = passes.length;
let res = 0;
// Process passes from top to bottom.
for (let i = 0; i < n; i++) {
// A visitor takes the current pass.
if (passes[i] === 0 && s0 > 0)
s0--;
else if (passes[i] === 1 && s1 > 0)
s1--;
// No visitor wants the current pass.
else {
res = n - i;
break;
}
}
return res;
}
// Driver code
let visitors = [ 1, 0, 0, 1 ];
let passes = [ 0, 0, 0, 1 ];
console.log(countVisitors(visitors, passes));
Output
2