设计一个电话目录管理系统,让它支持以下功能:
get
: 分配给用户一个未被使用的电话号码,获取失败请返回 -1check
: 检查指定的电话号码是否被使用release
: 释放掉一个电话号码,使其能够重新被分配
示例:
// 初始化电话目录,包括 3 个电话号码:0,1 和 2。 PhoneDirectory directory = new PhoneDirectory(3); // 可以返回任意未分配的号码,这里我们假设它返回 0。 directory.get(); // 假设,函数返回 1。 directory.get(); // 号码 2 未分配,所以返回为 true。 directory.check(2); // 返回 2,分配后,只剩一个号码未被分配。 directory.get(); // 此时,号码 2 已经被分配,所以返回 false。 directory.check(2); // 释放号码 2,将该号码变回未分配状态。 directory.release(2); // 号码 2 现在是未分配状态,所以返回 true。 directory.check(2);
提示:
1 <= maxNumbers <= 10^4
0 <= number < maxNumbers
- 调用方法的总数处于区间
[0 - 20000]
之内
解法1:队列
Java版:
class PhoneDirectory {
Queue<Integer> queue;
public PhoneDirectory(int maxNumbers) {
queue = new ArrayDeque<>();
for (int i = 0; i < maxNumbers; i++) {
queue.offer(i);
}
}
public int get() {
if (queue.isEmpty()) {
return -1;
}
return queue.poll();
}
public boolean check(int number) {
for (int q : queue) {
if (q == number) {
return true;
}
}
return false;
}
public void release(int number) {
if (!check(number)) {
queue.offer(number);
}
}
}
/**
* Your PhoneDirectory object will be instantiated and called as such:
* PhoneDirectory obj = new PhoneDirectory(maxNumbers);
* int param_1 = obj.get();
* boolean param_2 = obj.check(number);
* obj.release(number);
*/
Python3版:
class PhoneDirectory:
def __init__(self, maxNumbers: int):
self.queue = deque(list(range(maxNumbers)))
def get(self) -> int:
if self.queue:
return self.queue.popleft()
return -1
def check(self, number: int) -> bool:
return True if self.queue.count(number) > 0 else False
def release(self, number: int) -> None:
if not self.check(number):
self.queue.append(number)
# Your PhoneDirectory object will be instantiated and called as such:
# obj = PhoneDirectory(maxNumbers)
# param_1 = obj.get()
# param_2 = obj.check(number)
# obj.release(number)
解法2:队列 + 集合
Java版:
class PhoneDirectory {
Queue<Integer> queue;
Set<Integer> set;
public PhoneDirectory(int maxNumbers) {
queue = new ArrayDeque<>();
set = new HashSet<>();
for (int i = 0; i < maxNumbers; i++) {
queue.offer(i);
set.add(i);
}
}
public int get() {
if (queue.isEmpty()) {
return -1;
}
int v = queue.poll();
set.remove(v);
return v;
}
public boolean check(int number) {
if (set.contains(number)) {
return true;
}
return false;
}
public void release(int number) {
if (!set.contains(number)) {
queue.offer(number);
set.add(number);
}
}
}
/**
* Your PhoneDirectory object will be instantiated and called as such:
* PhoneDirectory obj = new PhoneDirectory(maxNumbers);
* int param_1 = obj.get();
* boolean param_2 = obj.check(number);
* obj.release(number);
*/
Python3版:
class PhoneDirectory:
def __init__(self, maxNumbers: int):
self.queue = deque(list(range(maxNumbers)))
self.set = set(list(range(maxNumbers)))
def get(self) -> int:
if not self.queue:
return -1
v = self.queue.popleft()
self.set.remove(v)
return v
def check(self, number: int) -> bool:
if number in self.set:
return True
return False
def release(self, number: int) -> None:
if number not in self.set:
self.queue.append(number)
self.set.add(number)
# Your PhoneDirectory object will be instantiated and called as such:
# obj = PhoneDirectory(maxNumbers)
# param_1 = obj.get()
# param_2 = obj.check(number)
# obj.release(number)
复杂度分析
- 时间复杂度:构造方法和每一项操作的时间复杂度是 O(1)。
- 空间复杂度:O(maxNumbers),其中 maxNumbers 是电话号码数量的上限。队列和哈希集合中的元素个数不超过 maxNumbers。