目录
【LeetCode1487】保证文件名唯一:题解与实现分析
题目描述
示例
输入:
输出:
解题思路分析
️ 解题方法:哈希表+模拟
✅ Python 实现
⏱️ 时间与空间复杂度分析
时间复杂度:
空间复杂度:
示例说明
方法对比与优化建议
小结与拓展
在我们使用计算机创建文件或文件夹时,系统会自动避免重名。例如,在你试图新建一个名为 doc
的文件夹,而该名字已存在时,系统可能会自动创建为 doc(1)
、doc(2)
等。这正是 LeetCode 第 1487 题的核心逻辑。
本文将带你逐步理解这道题的题意、算法设计思路、代码实现,以及时间复杂度分析和示例验证。
给你一个长度为 n
的字符串数组 names
,代表你依次在系统中创建的文件夹名称。
i
分钟,你试图创建名为 names[i]
的文件夹。(k)
的后缀,使其成为唯一的名称,k
是最小的正整数,确保新名字未被占用。请你返回一个数组 ans
,其中 ans[i]
是系统最终为第 i
个文件夹分配的唯一名称。
["doc", "doc", "image", "doc(1)", "doc"]
["doc", "doc(1)", "image", "doc(1)(1)", "doc(2)"]
我们需要为每一个文件夹名寻找一个唯一版本,这涉及两方面:
k=1
开始,逐个尝试添加后缀,直到找到未被占用的名字。这提示我们需要一个高效的数据结构,来快速判断名字是否被使用,同时还要能记录每个基础名字(如 "doc"
)已经使用到了哪一个 k
。
我们使用一个字典(哈希表)name_count
来追踪每个文件夹名出现的次数。关键逻辑如下:
result
和字典 name_count
。names
:name
没有被使用过:直接加入结果列表,并在 name_count
中记录其出现次数为 1。k = name_count[name]
开始尝试 name(k)
,直到找到一个未使用过的新名字。class Solution:
def getFolderNames(self, names: List[str]) -> List[str]:
name_count = {}
result = []
for name in names:
if name not in name_count:
result.append(name)
name_count[name] = 1
else:
k = name_count[name]
new_name = f"{name}({k})"
while new_name in name_count:
k += 1
new_name = f"{name}({k})"
result.append(new_name)
name_count[name] = k + 1
name_count[new_name] = 1
return result
k
才能找到一个合法的新名字。α
是冲突解决过程中最多尝试的后缀次数。但实际运行中,因为哈希表查找效率高,整体性能仍然非常优秀。n
个唯一文件名,因此是 O(n)。我们用一个实际输入来逐步演示代码逻辑:
输入:
["gta", "gta", "gta(1)", "gta"]
执行步骤如下:
步骤 |
输入名称 |
哈希表状态(name_count) |
输出结果 |
1 |
"gta" |
{"gta": 1} |
["gta"] |
2 |
"gta" |
{"gta": 2, "gta(1)": 1} |
["gta", "gta(1)"] |
3 |
"gta(1)" |
{"gta": 2, "gta(1)": 2, "gta(1)(1)":1} |
["gta", "gta(1)", "gta(1)(1)"] |
4 |
"gta" |
{"gta": 3, "gta(2)": 1, ...} |
["gta", "gta(1)", "gta(1)(1)", "gta(2)"] |
最终输出:
["gta", "gta(1)", "gta(1)(1)", "gta(2)"]
方法 |
说明 |
效率 |
暴力数组查重 |
每次都扫描 查找重复项 |
时间复杂度高 |
哈希表(本解法) |
通过字典快速判断是否重复,并记录每个基础名的下一个 |
时间效率极高 |
Trie 字典树 |
可以实现更结构化的存储,但过于复杂,不适合本题 |
不推荐 |
当前解法已经在效率与可读性之间取得了良好平衡,属于最优解法之一。
本题模拟了真实文件系统中处理重名文件夹的策略,考察了:
通过哈希表高效追踪使用记录,我们可以快速找到合法的文件夹名,从而应对大量输入数据。