给定一个二进制数组arr [] ,任务是设计一个数据结构,该结构支持O(1)中的以下操作。
- 类型1:从数组中删除并打印最左边的0 。
- 类型2:从阵列中删除并打印最左边的1 。
- 类型3:从数组中删除并打印最左边的元素。
如果任何请求的元素不在数组中,则打印-1。
例子:
Input: arr[] = {1, 0, 1, 1, 1}, q[] = {1, 3, 1}
Output:
0
1
-1
Type 1 query: Print 0 and the array become {1, 1, 1, 1}
Type 3 query: Print 1, arr[] = {1, 1, 1}
Type 1 query: There are no 0s left, so print -1
Input: arr[] = {1, 0, 1, 0, 1}, q[] = {3, 3, 3}
Output:
1
0
1
天真的方法:一种简单的方法是将所有元素插入支持先进先出的队列中。此方法将在O(1)中用于查找数组中最左边的元素,但无法找到O(1)中最左边的1或最左边的0。
高效方法:创建两个队列,第一个队列将按出现顺序存储0的索引,第二个队列将按出现顺序存储1s的索引。现在,可以按照以下步骤执行给定的操作:
- 类型1:打印删除O(1)中第一个队列的开头。
- 类型2:在O(1)中打印删除第二个队列的开头。
- 类型3:比较两个队列的开头,并返回具有最小索引的一个,然后将其删除。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// To store the indices of 0s and 1s
static queue zero;
static queue one ;
// Function to return the leftmost 0
static int getLeftMostZero()
{
// If there are no 0s
if (zero.empty())
return -1;
// pop the head of the queue
zero.pop();
return 0;
}
// Function to return the leftmost 1
static int getLeftMostOne()
{
// If there are no 1s
if (one.empty())
return -1;
// pop the head of the queue
one.pop();
return 1;
}
// Function to return the pre-calculate array
// such that arr[i] stores the count of
// valid numbers in the range [0, i]
int getLeftMostElement()
{
// If there are no elements left
if (zero.empty() && one.empty())
return -1;
// If only 1s are there
else if (zero.empty())
{
one.pop();
return 1;
}
// If only 0s are there
else if (one.empty())
{
zero.pop();
return 0;
}
// Get the element which is at
// the left-most position
int res = (zero.front() < one.front()) ? 0 : 1;
if (res == 0)
zero.pop();
else
one.pop();
return res;
}
// Function to perform the queries
void performQueries(int arr[], int n,
int queries[], int q)
{
for (int i = 0; i < n; i++)
{
if (arr[i] == 0)
zero.push(i);
else
one.push(i);
}
// For every query
for (int i = 0; i < q; i++)
{
// Get its type
int type = queries[i];
switch (type)
{
// Perform type 1 query
case 1:
cout << (getLeftMostZero())
<< endl;
break;
// Perform type 2 query
case 2:
cout << (getLeftMostOne())
<< endl;
break;
// Perform type 3 query
case 3:
cout << (getLeftMostElement())
<< endl;
break;
}
}
}
// Driver code
int main()
{
int arr[] = { 1, 0, 1, 1, 1 };
int n = sizeof(arr) / sizeof(int);
int queries[] = { 1, 3, 1 };
int q = sizeof(queries) / sizeof(int);
performQueries(arr, n, queries, q);
}
// This code is contributed by andrew1234
Java
// Java implementation of the approach
import java.util.*;
class GFG {
// Function to return the leftmost 0
static int getLeftMostZero(Queue zero)
{
// If there are no 0s
if (zero.isEmpty())
return -1;
// Remove the head of the queue
zero.remove();
return 0;
}
// Function to return the leftmost 1
static int getLeftMostOne(Queue one)
{
// If there are no 1s
if (one.isEmpty())
return -1;
// Remove the head of the queue
one.remove();
return 1;
}
// Function to return the pre-calculate array
// such that arr[i] stores the count of
// valid numbers in the range [0, i]
static int getLeftMostElement(Queue zero, Queue one)
{
// If there are no elements left
if (zero.isEmpty() && one.isEmpty())
return -1;
// If only 1s are there
else if (zero.isEmpty()) {
one.remove();
return 1;
}
// If only 0s are there
else if (one.isEmpty()) {
zero.remove();
return 0;
}
// Get the element which is at
// the left-most position
int res = (zero.peek() < one.peek()) ? 0 : 1;
if (res == 0)
zero.remove();
else
one.remove();
return res;
}
// Function to perform the queries
static void performQueries(int arr[], int n, int queries[], int q)
{
// To store the indices of 0s and 1s
Queue zero = new LinkedList<>();
Queue one = new LinkedList<>();
for (int i = 0; i < n; i++) {
if (arr[i] == 0)
zero.add(i);
else
one.add(i);
}
// For every query
for (int i = 0; i < q; i++) {
// Get its type
int type = queries[i];
switch (type) {
// Perform type 1 query
case 1:
System.out.println(getLeftMostZero(zero));
break;
// Perform type 2 query
case 2:
System.out.println(getLeftMostOne(one));
break;
// Perform type 3 query
case 3:
System.out.println(getLeftMostElement(zero, one));
break;
}
}
}
// Driver code
public static void main(String args[])
{
int arr[] = { 1, 0, 1, 1, 1 };
int n = arr.length;
int queries[] = { 1, 3, 1 };
int q = queries.length;
performQueries(arr, n, queries, q);
}
}
Python3
# Python3 implementation of the approach
from collections import deque
# To store the indices of 0s and 1s
zero = deque()
one = deque()
# Function to return the leftmost 0
def getLeftMostZero():
# If there are no 0s
if not len(zero):
return -1
# pop the head of the queue
zero.popleft()
return 0
# Function to return the leftmost 1
def getLeftMostOne():
# If there are no 1s
if not len(one):
return -1
# pop the head of the queue
one.popleft()
return 1
# Function to return the pre-calculate array
# such that arr[i] stores the count of
# valid numbers in the range [0, i]
def getLeftMostElement():
# If there are no elements left
if not len(zero) and not len(one):
return -1
# If only 1s are there
elif not len(zero):
one.popleft()
return 1
# If only 0s are there
elif not len(one):
zero.popleft()
return 0
# Get the element which is at
# the left-most position
res = 0 if zero[0] < one[0] else 1
if res == 0:
zero.popleft()
else:
one.popleft()
return res
# Function to perform the queries
def performQueries(arr: list, n: int, queries: list, q: int):
for i in range(n):
if arr[i] == 0:
zero.append(i)
else:
one.append(i)
# For every query
for i in range(q):
# Get its type
type = queries[i]
# Perform type 1 query
if type == 1:
print(getLeftMostZero())
# Perform type 2 query
elif type == 2:
print(getLeftMostOne())
# Perform type 3 query
elif type == 3:
print(getLeftMostElement())
# Driver Code
if __name__ == "__main__":
arr = [1, 0, 1, 1, 1]
n = len(arr)
queries = [1, 3, 1]
q = len(queries)
performQueries(arr, n, queries, q)
# This code is contributed by
# sanjeev2552
C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to return the leftmost 0
static int getLeftMostZero(Queue zero)
{
// If there are no 0s
if (zero.Count == 0)
return -1;
// Remove the head of the queue
zero.Dequeue();
return 0;
}
// Function to return the leftmost 1
static int getLeftMostOne(Queue one)
{
// If there are no 1s
if (one.Count == 0)
return -1;
// Remove the head of the queue
one.Dequeue();
return 1;
}
// Function to return the pre-calculate array
// such that arr[i] stores the count of
// valid numbers in the range [0, i]
static int getLeftMostElement(Queue zero,
Queue one)
{
// If there are no elements left
if (zero.Count == 0 && one.Count == 0)
return -1;
// If only 1s are there
else if (zero.Count == 0)
{
one.Dequeue();
return 1;
}
// If only 0s are there
else if (one.Count == 0)
{
zero.Dequeue();
return 0;
}
// Get the element which is at
// the left-most position
int res = (zero.Peek() < one.Peek()) ? 0 : 1;
if (res == 0)
zero.Dequeue();
else
one.Dequeue();
return res;
}
// Function to perform the queries
static void performQueries(int []arr, int n,
int []queries, int q)
{
// To store the indices of 0s and 1s
Queue zero = new Queue();
Queue one = new Queue();
for (int i = 0; i < n; i++)
{
if (arr[i] == 0)
zero.Enqueue(i);
else
one.Enqueue(i);
}
// For every query
for (int i = 0; i < q; i++)
{
// Get its type
int type = queries[i];
switch (type)
{
// Perform type 1 query
case 1:
Console.WriteLine(getLeftMostZero(zero));
break;
// Perform type 2 query
case 2:
Console.WriteLine(getLeftMostOne(one));
break;
// Perform type 3 query
case 3:
Console.WriteLine(getLeftMostElement(zero, one));
break;
}
}
}
// Driver code
public static void Main(String []args)
{
int []arr = { 1, 0, 1, 1, 1 };
int n = arr.Length;
int []queries = { 1, 3, 1 };
int q = queries.Length;
performQueries(arr, n, queries, q);
}
}
// This code is contributed by PrinciRaj1992
输出:
0
1
-1