
Problem Statement
The objective is to design a phone directory system where initially there are maxNumbers
empty slots that can store phone numbers. Each slot can only store one phone number at a time.
The PhoneDirectory
class should be able to:
- Initialize the phone directory with a specified number of available slots.
- Provide an unassigned number which isn't already given out.
- Check the status of a specific slot (whether it is available or not).
- Recycle or release a number back into the directory to make the slot available again.
For instance:
- The constructor
PhoneDirectory(int maxNumbers)
sets up the directory withmaxNumbers
slots. - The method
int get()
returns the next available number, or-1
if no numbers are available. - The method
bool check(int number)
checks if a particular number is available (returnstrue
) or not (returnsfalse
). - The method
void release(int number)
releases a previously assigned number, making it available again.
These functions ensure efficient management of available and assigned phone numbers within specified limits.
Examples
Example 1
Input
["PhoneDirectory", "get", "get", "check", "get", "check", "release", "check"] [[3], [], [], [2], [], [2], [2], [2]]
Output
[null, 0, 1, true, 2, false, null, true]
Explanation
PhoneDirectory phoneDirectory = new PhoneDirectory(3); phoneDirectory.get(); // It can return any available phone number. Here we assume it returns 0. phoneDirectory.get(); // Assume it returns 1. phoneDirectory.check(2); // The number 2 is available, so return true. phoneDirectory.get(); // It returns 2, the only number that is left. phoneDirectory.check(2); // The number 2 is no longer available, so return false. phoneDirectory.release(2); // Release number 2 back to the pool. phoneDirectory.check(2); // Number 2 is available again, return true.
Constraints
1 <= maxNumbers <= 104
0 <= number < maxNumbers
- At most
2 * 104
calls will be made toget
,check
, andrelease
.
Approach and Intuition
Understanding the Requirements:
- The directory begins with all slots unassigned. Each slot corresponds to an integer from
0
tomaxNumbers-1
. - An available number is retrieved and marked as unavailable when
get()
is called. - We can check if a number is available using
check(int number)
. - A number can be released (made available again) using
release(int number)
.
Example Walk-through based on the given example:
Initialization:
- Instantiate the phone directory with 3 numbers. All numbers (0, 1, and 2) are initially available.
Get Operations:
- Call
get()
: Returns 0, the first available number. Now, the available numbers are 1 and 2. - Call
get()
again: Returns 1. Now, the only available number is 2.
- Call
Check Operation:
- Call
check(2)
: Returns true since 2 is still available.
- Call
Get Operation:
- Call
get()
: Returns 2. Now, no numbers are left. All numbers (0, 1, and 2) are assigned.
- Call
Check Operation:
- Call
check(2)
: Returns false since 2 is now assigned and not available.
- Call
Release Operation:
- Call
release(2)
: This makes number 2 available again.
- Call
Check Operation:
- Call
check(2)
: Returns true now since 2 is available again after release.
- Call
Structural Implementation Details:
- Maintain a set or list to keep track of available numbers.
- Utilize efficient data structures to ensure that operations like
get
,check
, andrelease
happen in reasonable time, especially given the constraints that up to2 * 104
calls might be made. - Handling edge cases such as releasing an already available number or getting when no numbers are available are crucial to prevent errors.
Implementing the above methods with attention to performance while effectively managing available and assigned slots will provide a robust phone directory system.
Solutions
- C++
- Java
- JavaScript
- Python
class DirectoryService {
unordered_set<int> availableNumbers;
public:
DirectoryService(int maxNumbers) {
for (int idx = 0; idx < maxNumbers; ++idx) {
availableNumbers.insert(idx);
}
}
int acquire() {
if (availableNumbers.empty()) {
return -1;
}
int num = *(availableNumbers.begin());
availableNumbers.erase(num);
return num;
}
bool isAvailable(int number) {
return availableNumbers.find(number) != availableNumbers.end();
}
void free(int number) {
availableNumbers.insert(number);
}
};
The provided C++ program defines a class DirectoryService
that simulates a phone directory service where numbers can be acquired, checked for availability, and released. Here's how the class operations work:
Constructor (
DirectoryService(int maxNumbers)
): Initializes the directory with a set of phone numbers ranging from 0 tomaxNumbers - 1
. Each number is inserted into an unordered setavailableNumbers
, making these numbers available for acquisition.Acquire Method (
int acquire()
): Provides the first available phone number from the set. If no numbers are available (i.e., the set is empty), it returns-1
to indicate that no numbers can be acquired. It removes the acquired number from theavailableNumbers
set to ensure it is not issued again until it's released.IsAvailable Method (
bool isAvailable(int number)
): Checks if a specific number is available for acquisition by searching for the number inavailableNumbers
. Returnstrue
if the number exists in the set (is available), otherwise returnsfalse
.Free Method (
void free(int number)
): Reinserts a previously acquired number back into theavailableNumbers
set, making it available for future acquisitions. This method effectively allows a number to be reused after it's released.
This design offers a straightforward mechanism for phone number management within a defined range, using set operations for efficiently handling the availability of numbers.
class ContactDirectory {
private Set<Integer> availableSlots;
public ContactDirectory(int maxNumbers) {
availableSlots = new HashSet<>();
for (int i = 0; i < maxNumbers; i++) {
availableSlots.add(i);
}
}
public int acquire() {
if (availableSlots.isEmpty()) {
return -1;
}
int acquiredNumber = availableSlots.iterator().next();
availableSlots.remove(acquiredNumber);
return acquiredNumber;
}
public boolean isAvailable(int number) {
return availableSlots.contains(number);
}
public void free(int number) {
availableSlots.add(number);
}
}
The given Java code implements a class named ContactDirectory
that manages a phone directory, enabling you to acquire, check availability, and free up phone numbers. Here's how the class is structured and operates:
Initialize
ContactDirectory
with a specified number of maximum available phone numbers. This is done through the constructor which acceptsmaxNumbers
. It uses aHashSet
to track and store all available phone numbers from 0 up tomaxNumbers - 1
.The
acquire
method allows you to request a phone number. If numbers are available, it retrieves and removes a number from the set of available numbers and returns it. If no numbers are available, it returns -1.The
isAvailable
method checks if a specific number is available within the directory. Returnstrue
if the number is still in the set of available numbers, indicating it hasn't been acquired yet, andfalse
otherwise.The
free
method releases a previously acquired number back to the directory, making it available again for acquisition.
This implementation ensures efficient management of phone numbers in a directory, using Java's Set
data structure to handle operations with good performance for adding, checking, and removing elements.
var DirectoryService = function(maxNumbers) {
this.availableNumbers = new Set([...Array(maxNumbers).keys()]);
};
DirectoryService.prototype.obtain = function() {
if (this.availableNumbers.size === 0) {
return -1;
}
const num = this.availableNumbers.values().next().value;
this.availableNumbers.delete(num);
return num;
};
DirectoryService.prototype.isPresent = function(number) {
return this.availableNumbers.has(number);
};
DirectoryService.prototype.free = function(number) {
this.availableNumbers.add(number);
};
The solution provided outlines an implementation of a phone directory management system in JavaScript. Here’s how each part of the code works and their functions:
The
DirectoryService
function constructs an object where a set calledavailableNumbers
stores all the potential phone numbers that can be assigned. The numbers range from 0 tomaxNumbers - 1
.DirectoryService.prototype.obtain
allows for fetching and removing the first available number from the set. If no numbers are available, it returns-1
. This ensures that once a number is obtained, it’s no longer available in the directory until released.DirectoryService.prototype.isPresent
checks whether a particular number is still available in the directory. It returns a boolean indicating the presence of the number in the setavailableNumbers
.Lastly, the
DirectoryService.prototype.free
method adds a number back to the set, making it available again for allocation. This is particularly useful for recycling or reusing numbers that were previously in use but are now free.
This structure supports basic operations required for managing a pool of phone numbers efficiently, ensuring that there are no duplicates in active usage and numbers can be easily recycled. The use of JavaScript's Set
provides an efficient way of handling the uniqueness and order of numbers.
class DirectoryService:
def __init__(self, max_slots):
self.available_slots = set(range(max_slots))
def acquire(self):
if not self.available_slots:
return -1
return self.available_slots.pop()
def is_available(self, slot):
return slot in self.available_slots
def free_up(self, slot):
self.available_slots.add(slot)
This Python solution outlines a simple approach to designing a phone directory service. The solution uses a class DirectoryService
that manages the availability of phone numbers using a set data structure to store vacant slots for efficient access and manipulation.
- Initialize the Directory Service with a specified maximum number of available slots using the
__init__
method. This sets up all slots as initially available. - Use the
acquire
method to allocate an available slot. If no slots are available, the method returns -1. - Implement the
is_available
method to check if a specific slot is currently available. It returns a boolean. - Define the
free_up
method to release a slot that is no longer in use, adding it back to the set of available slots.
This approach ensures that acquiring and freeing up slots are operations that can be performed efficiently, and checking slot availability is straightforward.
No comments yet.