怎样建立一个营销的公司网站网络广告商
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。
为了方便在PC上运行调试、分享代码文件,我还建立了相关的仓库。在这一仓库中,你不仅可以看到LeetCode原题链接、题解代码、题解文章链接、同类题目归纳、通用解法总结等,还可以看到原题出现频率和相关企业等重要信息。如果有其他优选题解,还可以一同分享给他人。
由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏征服LeetCode系列文章目录一文以作备忘。
Given an array of strings names of size n. You will create n folders in your file system such that, at the ith minute, you will create a folder with the name names[i].
Since two files cannot have the same name, if you enter a folder name that was previously used, the system will have a suffix addition to its name in the form of (k), where, k is the smallest positive integer such that the obtained name remains unique.
Return an array of strings of length n where ans[i] is the actual name the system will assign to the ith folder when you create it.
Example 1:
Input: names = ["pes","fifa","gta","pes(2019)"]
Output: ["pes","fifa","gta","pes(2019)"]
Explanation: Let's see how the file system creates folder names:
"pes" --> not assigned before, remains "pes"
"fifa" --> not assigned before, remains "fifa"
"gta" --> not assigned before, remains "gta"
"pes(2019)" --> not assigned before, remains "pes(2019)"
 
Example 2:
Input: names = ["gta","gta(1)","gta","avalon"]
Output: ["gta","gta(1)","gta(2)","avalon"]
Explanation: Let's see how the file system creates folder names:
"gta" --> not assigned before, remains "gta"
"gta(1)" --> not assigned before, remains "gta(1)"
"gta" --> the name is reserved, system adds (k), since "gta(1)" is also reserved, systems put k = 2. it becomes "gta(2)"
"avalon" --> not assigned before, remains "avalon"
 
Example 3:
Input: names = ["onepiece","onepiece(1)","onepiece(2)","onepiece(3)","onepiece"]
Output: ["onepiece","onepiece(1)","onepiece(2)","onepiece(3)","onepiece(4)"]
Explanation: When the last folder is created, the smallest positive valid k is 4, and it becomes "onepiece(4)".
 
Constraints:
1 <= names.length <= 5 * 1041 <= names[i].length <= 20names[i]consists of lowercase English letters, digits, and/or round brackets.
题意:给定一个长度为 n 的字符串数组 names ,你在你的文件系统中依次创建文件夹 names[i] 。由于两个文件不能同名,如果你输入了一个已经存在的名字,系统会给该名字后面加上一个后缀 (k) ,k 是使文件名字唯一的最小正整数。
解法 模拟+哈希表+字符串
一开始想复杂了,现在连想得多么复杂都不愿想起来了。总之,这个题目就是模拟文件系统的命名机制,给出一个文件名 names[i] ,如果没有出现过,则直接命名为 names[i] ;如果出现过,则从 (1) 开始给 names[i] 添加后缀 (k) ,直到找到没有出现过的文件名 "names[i](k)" ,这的 k 就是使文件名字唯一的最小正整数。
多说无益,看看几个示例:
- 对于 
["pes","fifa","gta","pes(2019)"],其中每个名字在之前都没出现过,所以输出就是["pes","fifa","gta","pes(2019)"]。 - 对于 
["gta","gta(1)","gta","avalon"],"gta", "gta(1)"在之前都没出现过,直接加入答案数组;后面的"gta"则在前面出现过,所以先加后缀命名为"gta(1)",发现也出现过,于是命名为"gta(2)",没有出现过,直接加入答案数组。输出就是["gta","gta(1)","gta(2)","avalon"]。 - 对于 
["gta","gta(1)","gta","gta(2)"],前三个都是一样,到第四个"gta(2)"时,发现它出现过,和第三个"gta"重新命名后的名字相同,那就需要在"gta(2)"后面加后缀,先变为"gta(2)(1)",发现没有出现过,就直接加入答案数组。 
看了这几个示例,代码写起来也很简单了:使用哈希表 rec 存储所有第一次出现(包括「添加后缀之后首次出现」的字符串)的字符串、和后面的同名字符串将要使用的数字(一开始是1)。每次从 names 拿到一个新名字 names[i] 时:
- 先判断 
rec中是否存在,若不存在,说明之前没出现过,可直接用作文件名,此时rec[names[i]] = 1; - 否则,设 
s = names[i],然后不断从rec中取出names[i]已经使用的数字k作为后缀拼在s后面,++rec[names[i]。如果这一名字也已在rec中,就继续循环这一步,直到得到新的文件名,并设置rec[s] = 1。 
- 时间复杂度:O(n)O(n)O(n) 。如果都是不同字符串,则全部名字都可直接用,遍历一遍 
names数组即可;如果都是相同字符串,则要依次取rec[names[i]]、添加新的后缀、++rec[names[i]]。 - 空间复杂度:O(n)O(n)O(n)
 
class Solution {public String[] getFolderNames(String[] names) {String[] ans = new String[names.length];var rec = new HashMap<String, Integer>();for (int i = 0; i < names.length; ++i) {String s = names[i];while (rec.containsKey(s) ) {int suffix = rec.get(names[i]);s = names[i] + "(" + suffix + ")";rec.put(names[i], suffix + 1);}rec.put(s, 1);ans[i] = s;}return ans;}
}
