
Problem Statement
Design a class FirstUnique
that manages a queue of integers and supports three operations efficiently:
FirstUnique(int[] nums)
: Initializes the queue with an array of integers.int showFirstUnique()
: Returns the first unique integer in the queue. If no such integer exists, return-1
.void add(int value)
: Adds a new integer to the end of the queue.
The solution must ensure that operations are fast and scalable for large input sizes.
Examples
Example 1
Input:
["FirstUnique","showFirstUnique","add","showFirstUnique","add","showFirstUnique","add","showFirstUnique"] [[[2,3,5]],[],[5],[],[2],[],[3],[]]
Output:
[null,2,null,2,null,3,null,-1]
Explanation:
FirstUnique firstUnique = new FirstUnique([2,3,5]) firstUnique.showFirstUnique() => 2 firstUnique.add(5) => queue = [2,3,5,5] firstUnique.showFirstUnique() => 2 firstUnique.add(2) => queue = [2,3,5,5,2] firstUnique.showFirstUnique() => 3 firstUnique.add(3) => queue = [2,3,5,5,2,3] firstUnique.showFirstUnique() => -1
Example 2
Input:
["FirstUnique","showFirstUnique","add","add","add","add","add","showFirstUnique"] [[[7,7,7,7,7,7]],[],[7],[3],[3],[7],[17],[]]
Output:
[null,-1,null,null,null,null,null,17]
Example 3
Input:
["FirstUnique","showFirstUnique","add","showFirstUnique"] [[[809]],[],[809],[]]
Output:
[null,809,null,-1]
Constraints
1 <= nums.length <= 10^5
1 <= nums[i], value <= 10^8
- At most
50000
calls will be made toshowFirstUnique
andadd
.
Approach and Intuition
The challenge lies in dynamically identifying the first unique integer while supporting fast add
and showFirstUnique
operations. A naïve scan of the queue each time is inefficient. Instead, we use:
1. Hash Map (occurrences
)
- Tracks how many times each number has appeared.
- Time complexity: O(1) for updates and lookups.
2. Queue or Linked Set (uniqueQueue
)
- Maintains the insertion order of unique integers.
- Elements are only present if their count is exactly 1.
- Time complexity: O(1) for peek, add, and remove.
3. Operations
Constructor (
FirstUnique(nums)
):For each number:
- Increment its count in
occurrences
. - If it's the first time, add to
uniqueQueue
. - If the count becomes >1, remove it from
uniqueQueue
if it exists.
- Increment its count in
showFirstUnique()
:- Return the front element of
uniqueQueue
if it exists. - If no unique element remains, return
-1
.
- Return the front element of
add(value)
:- Same logic as constructor for adding a new number and updating the unique tracker.
This approach ensures that operations run in constant time on average, which is critical under the given constraints.
Solutions
- Java
- Python
class UniqueTracker {
private Set<Integer> queueSet = new LinkedHashSet<>();
private Map<Integer, Boolean> mapUnique = new HashMap<>();
public UniqueTracker(int[] elements) {
for (int element : elements) {
this.add(element);
}
}
public int showFirstUnique() {
if (!queueSet.isEmpty()) {
return queueSet.iterator().next();
}
return -1;
}
public void add(int number) {
if (!mapUnique.containsKey(number)) {
mapUnique.put(number, true);
queueSet.add(number);
} else if (mapUnique.get(number)) {
mapUnique.put(number, false);
queueSet.remove(number);
}
}
}
The provided Java code is designed to manage and identify the first unique number in a stream of integers using a combination of a HashSet and a HashMap. The functionality is encapsulated within the UniqueTracker
class, which performs the operations using a set (queueSet
) to maintain insertion order and a map (mapUnique
) to track the uniqueness of numbers.
- The
UniqueTracker
constructor takes an array of integers and adds them to the structure by calling theadd
method for each element. - The
showFirstUnique
method checks if thequeueSet
is not empty and returns the first element, which is guaranteed to be the first unique number since it preserves insertion order. If the set is empty, it returns -1, indicating no unique number is present. - The
add
method processes a new number each time it is called:- If the number is not already in
mapUnique
, it adds the number to bothmapUnique
(setting its value to true to denote it as unique) andqueueSet
. - If the number is already in
mapUnique
and its value is true (indicating it was considered unique before), it sets its value to false (no longer unique) and removes it fromqueueSet
.
- If the number is not already in
Through these operations, the UniqueTracker
efficiently tracks and updates the first unique number in real-time, providing an effective solution for problems that require such functionality.
from collections import OrderedDict
class UniqueNumberTracker:
def __init__(self, numbers: List[int]):
self._data = OrderedDict()
self._unique_flags = {}
for number in numbers:
self.append(number)
def findFirstUnique(self) -> int:
if self._data:
return next(iter(self._data))
return -1
def append(self, number: int) -> None:
if number not in self._unique_flags:
self._unique_flags[number] = True
self._data[number] = None
else:
if self._unique_flags[number]:
self._unique_flags[number] = False
self._data.pop(number)
The Python program provided implements a class UniqueNumberTracker
utilizing the OrderedDict
from the collections
module to manage and track unique numbers efficiently.
- At initialization (
__init__
method), the tracker accepts a list of integers. Each number is processed to determine if it is unique by adding it to anOrderedDict
_data
. This ensures that the insertion order is maintained, which is crucial for determining the first unique number. - The
findFirstUnique
method checks if the_data
dictionary has entries and returns the first key (which represents the first unique number) if present. If the dictionary is empty, indicating no unique numbers, it returns-1
. - The
append
method allows addition of new numbers to the tracker. It includes logic to:- Add the number as unique if it’s not already in the
_unique_flags
dictionary. - If already present and flagged as unique, the number is marked as not unique and removed from the
_data
dictionary to reflect this change.
- Add the number as unique if it’s not already in the
This setup allows for efficient tracking and retrieval of the first unique number from a stream of data, by keeping up-to-date records of each number’s uniqueness status and order of occurrence.
No comments yet.