当前位置: 首页 > news >正文

LeetCode 379 - 电话目录管理系统(Design Phone Directory)

在这里插入图片描述
在这里插入图片描述

文章目录

    • 摘要
    • 描述
    • 题解答案
    • 题解代码分析
      • 代码解析
    • 示例测试及结果
      • 输出结果
    • 时间复杂度
    • 空间复杂度
    • 总结

摘要

在日常软件开发中,我们常常需要设计类似“资源池”的功能,比如电话号码分配、账号生成、甚至是座位预定。资源池的关键点就是:要能快速分配、检查和回收。LeetCode 第 379 题“电话目录管理系统”就是一个很典型的资源池设计问题,它要求我们在有限的号码池中进行高效的分配和管理。

这道题不仅考察了数据结构的应用,还非常贴近实际场景。本文会带你从需求出发,一步步拆解实现,并且写出可运行的 Swift Demo。

描述

题目描述如下:

设计一个电话目录管理系统,支持以下 3 个操作:

  1. get(): 提供一个未分配的号码,如果没有可用号码则返回 -1。
  2. check(number): 检查某个号码是否未被分配。
  3. release(number): 释放某个号码,将它重新放回号码池。

初始化时,系统会指定一个上限 maxNumbers,即最多可以存放多少个号码,号码范围是从 0maxNumbers - 1

例如:

PhoneDirectory directory = new PhoneDirectory(3);
directory.get();      // 返回 0
directory.get();      // 返回 1
directory.check(2);   // 返回 true
directory.get();      // 返回 2
directory.check(2);   // 返回 false
directory.release(2); // 释放号码 2
directory.check(2);   // 返回 true

题解答案

我们要实现一个支持 分配、检查、释放 的号码池,关键有几点:

  • 快速获取一个未分配的号码
  • 快速判断某个号码是否已分配
  • 快速释放号码,并且保证后续可以再次分配

常见的解法有两种:

  1. 用队列(或集合)保存所有可用的号码,每次 get() 从队列里取一个。
  2. 用一个布尔数组(或哈希集合)来标记某个号码是否被使用。

我们可以结合这两种思路:

  • 队列 存储未分配的号码。
  • Set 记录当前已分配的号码,方便 check 操作。

这样可以在 O(1) 的时间内完成所有操作。

题解代码分析

下面是 Swift 的完整实现:

import Foundationclass PhoneDirectory {private var available: [Int]   // 队列,存储未分配的号码private var used: Set<Int>     // 已分配的号码集合init(_ maxNumbers: Int) {self.available = Array(0..<maxNumbers)self.used = Set<Int>()}// 获取一个未分配的号码func get() -> Int {if available.isEmpty {return -1}let number = available.removeFirst()used.insert(number)return number}// 检查号码是否可用func check(_ number: Int) -> Bool {return !used.contains(number)}// 释放号码func release(_ number: Int) {if used.contains(number) {used.remove(number)available.append(number)}}
}

代码解析

  1. 初始化

    • available 队列存储从 0maxNumbers - 1 的所有号码。
    • used 集合存储已经分配出去的号码。
  2. get()

    • 如果 available 队列为空,说明没有号码可用了,返回 -1。
    • 否则取出队首号码,并把它放入 used 集合。
  3. check(number)

    • 如果号码不在 used 集合里,就说明可用。
  4. release(number)

    • 如果号码在 used 里,就从 used 移除,并放回 available 队列。

示例测试及结果

我们来写一个小 Demo 测试一下:

let directory = PhoneDirectory(3)print(directory.get())    // 输出 0
print(directory.get())    // 输出 1
print(directory.check(2)) // 输出 true
print(directory.get())    // 输出 2
print(directory.check(2)) // 输出 false
directory.release(2)      
print(directory.check(2)) // 输出 true

输出结果

0
1
true
2
false
true

和题目要求完全一致。

时间复杂度

  • get() 操作:O(1),因为队列取数和集合插入都是常数时间。
  • check() 操作:O(1),哈希集合查询。
  • release() 操作:O(1),集合删除和队列添加。

因此整体是 O(1),非常高效。

空间复杂度

  • available 队列存储最多 maxNumbers 个号码。
  • used 集合同样最多存储 maxNumbers 个号码。

因此空间复杂度是 O(maxNumbers)

总结

这道题本质上就是一个 号码池(资源池)管理系统,关键点是保证操作的高效性。我们用队列存储可用号码,用集合存储已用号码,这样每个操作都能在 O(1) 时间内完成。

在实际场景中,这个思路同样适用:

  • 数据库连接池:管理空闲和使用中的连接。
  • 账号/工号分配系统:快速生成和回收账号。
  • IP 地址池管理:分配和释放 IP 地址。

所以这道题不仅是个数据结构练习,更是很多工程实践中的缩影。


文章转载自:

http://XclP1jjk.nktyq.cn
http://tcYYRqWq.nktyq.cn
http://eIlJ97WE.nktyq.cn
http://Rz9m7EQr.nktyq.cn
http://DRyhtG8v.nktyq.cn
http://ab3DLHOZ.nktyq.cn
http://bvnjsg6K.nktyq.cn
http://EK5AenO6.nktyq.cn
http://q9rtBQi4.nktyq.cn
http://rl9WFmgx.nktyq.cn
http://9c7Facax.nktyq.cn
http://F5Hc419D.nktyq.cn
http://mQ7HnPUP.nktyq.cn
http://UDN59oCI.nktyq.cn
http://7HIKTOz0.nktyq.cn
http://g59rCHY8.nktyq.cn
http://JaHAnN7G.nktyq.cn
http://63AUHVS0.nktyq.cn
http://2Lipx6FT.nktyq.cn
http://xGxtxp8y.nktyq.cn
http://KhOMwVuA.nktyq.cn
http://jCqcSdAN.nktyq.cn
http://VUeOBXHb.nktyq.cn
http://Ny3OwE0r.nktyq.cn
http://pz3gIzbL.nktyq.cn
http://xCT0sytR.nktyq.cn
http://bsae0aVY.nktyq.cn
http://HfOv4ed0.nktyq.cn
http://k7EzdZnX.nktyq.cn
http://nD2302O6.nktyq.cn
http://www.dtcms.com/a/384279.html

相关文章:

  • 《Python 自动化实战:从零构建一个文件同步工具》
  • 风险规则引擎-RPA 作为自动化依赖业务决策流程的强大工具
  • Vue: 模板引用 (Template Refs)
  • Web2 vs Web3
  • 上海交大3D体素赋能具身导航!BeliefMapNav:基于3D体素信念图的零样本目标导航
  • SAP-ABAP:SAP ABAP中的JSON序列化利器:/UI2/CL_JSON=>SERIALIZE完全指南实例详解
  • stm32 can错误处理问题
  • python 自动化从入门到实战-开发一个随机点名系统(6)
  • 如何用 GitHub Actions 为 FastAPI 项目打造自动化测试流水线?
  • godot+visual studio配置c#环境
  • 文件查找失败:‘module‘ at node_modules\sass\sass.node.js:7
  • (一)Vue.js 框架简介
  • Vue 中在 Vue 项目中引入 Cesium 并加载本地离线地图
  • Node.js ≥ 18 安装教程
  • 第四阶段C#通讯开发-4:网络通讯_网络协议
  • 如何实现测试环境隔离临时数据库(pytest+SQLite)
  • 像连接mysql一样连接mongodb
  • 从零开始搞定C++类和对象(下)
  • 企业级实战:构建基于Qt、C++与YOLOv8的模块化工业视觉检测系统
  • TexturePacker 打包 TextAtlas:按顺序排列
  • MyBatis 核心概念与实践指南:从代理模式到性能优化
  • 全链路性能优化实战:从Jmeter压测到系统调优
  • 《华为变革法:打造可持续进步的组织》读书笔记
  • VS Code 通用配置分享(Cursor / QCode / Trae 通用)
  • python 自动化从入门到实战-word转为 PDF 文件(4)
  • Python爬虫实战:研究Pandas,构建地理信息数据采集和分析系统
  • 【Linux】进程概念(二):进程查看与 fork 初探
  • Python 自动化从入门到实战-一键将 Excel 表格转为 PDF 文件(3)
  • FFMPEG FLV
  • Spring Cloud Alibaba 与 Spring Boot、Spring Cloud 的版本兼容性对照