题目来源:🔒LeetCode 379:电话目录管理系统
问题抽象: 设计一个 电话目录管理系统,管理 0 至 maxNumbers-1 的号码资源,要求实现以下核心操作:
-
功能定义:
get():分配一个 当前可用 的号码(任意顺序),无可用时返回-1;check(number):检查号码number是否 未被分配(可用);release(number):释放一个已分配号码,使其 可重新分配。
-
数据结构要求:
- 初始化时所有号码均可用(
maxNumbers > 0); - 需支持高效分配和释放操作(时间复杂度 O(1));
- 使用 队列 存储可用号码(分配时出队),布尔数组/集合 记录状态(查询和释放时验证)。
- 初始化时所有号码均可用(
-
操作约束:
get():- 若队列非空 → 弹出队首号码,标记为已分配,返回该号码;
- 若队列为空 → 返回
-1;
check(number):- 检查
number是否在可用集合中(或布尔数组为true);
- 检查
release(number):- 若
number有效且已分配 → 重置为可用状态,重新入队; - 若
number无效或未分配 → 忽略(幂等操作)。
- 若
-
边界处理:
- 号码范围:
0 ≤ number < maxNumbers(超出则check/release无效); - 重复释放:多次释放同一号码不改变状态(如先
release(1),再release(1)→ 第二次无效); - 特殊用例:
maxNumbers=1:get()→ 返回0;check(0)→false;release(0)后check(0)→true;
maxNumbers=3:get(),get(),get()依次返回0,1,2→ 再get()返回-1;release(1)后check(1)为true,get()返回1。
- 号码范围:
输入:
- 构造函数:
maxNumbers(整数,1 ≤ maxNumbers ≤ 10^4); - 方法参数:
number(0 ≤ number < maxNumbers)。
输出:
get():整数值(分配号码或-1);check(number):布尔值(true表示可用);release(number):无返回值。
解题思路
为了实现高效的电话目录管理系统,采用以下设计:
- 布尔数组标记状态:使用数组
used记录每个号码的分配状态(true表示已分配,false表示可用)。 - 队列管理可用号码:使用队列
availableQueue存储当前可用的号码,确保get操作能快速获取号码。 - 操作细节:
- 初始化:所有号码初始可用,加入队列并设置
used[i] = false。 get:从队列弹出号码(队列空返回-1),标记为已分配(used[num] = true)。check:直接检查used数组状态(!used[number])。release:检查号码是否已分配(used[number] == true),是则重置为可用(used[number] = false)并加入队列。
- 初始化:所有号码初始可用,加入队列并设置
代码实现(Java版)🔥点击下载源码
class PhoneDirectory {
private boolean[] used; // 记录号码是否被分配
private Queue<Integer> availableQueue; // 存储可用号码的队列
public PhoneDirectory(int maxNumbers) {
used = new boolean[maxNumbers];
availableQueue = new LinkedList<>();
// 初始化:所有号码均可用
for (int i = 0; i < maxNumbers; i++) {
availableQueue.offer(i);
}
}
public int get() {
if (availableQueue.isEmpty()) {
return -1; // 无可用号码
}
int num = availableQueue.poll();
used[num] = true; // 标记为已分配
return num;
}
public boolean check(int number) {
// 检查号码是否在合法范围且未被分配
return number >= 0 && number < used.length && !used[number];
}
public void release(int number) {
// 仅当号码已被分配时才释放
if (number >= 0 && number < used.length && used[number]) {
used[number] = false; // 重置为可用
availableQueue.offer(number); // 加入可用队列
}
}
}
代码说明
-
初始化:
- 创建长度为
maxNumbers的布尔数组used(默认false表示可用)。 - 将所有号码(0 至 maxNumbers-1)加入队列
availableQueue。
- 创建长度为
-
get方法:- 若队列为空返回
-1,否则弹出队首号码。 - 标记该号码为已分配(
used[num] = true),并返回号码。
- 若队列为空返回
-
check方法:- 检查号码是否在有效范围(0 至 maxNumbers-1)。
- 直接返回
!used[number](true表示可用)。
-
release方法:- 检查号码是否合法且已被分配(
used[number] == true)。 - 重置状态为可用(
used[number] = false),并加入队列。
- 检查号码是否合法且已被分配(
优势:时间复杂度:所有操作均为 O(1)。空间复杂度:O(n),仅使用必要存储。高效性:队列确保快速获取号码,数组保证状态检查高效。

679

被折叠的 条评论
为什么被折叠?



