【算法】【c++】1487. Making File Names Unique

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 which is 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)”.
Example 4:

Input: names = [“wano”,“wano”,“wano”,“wano”]
Output: [“wano”,“wano(1)”,“wano(2)”,“wano(3)”]
Explanation: Just increase the value of k each time you create folder “wano”.
Example 5:

Input: names = [“kaido”,“kaido(1)”,“kaido”,“kaido(1)”]
Output: [“kaido”,“kaido(1)”,“kaido(2)”,“kaido(1)(1)”]
Explanation: Please note that system adds the suffix (k) to current name even it contained the same suffix before.

Constraints:

1 <= names.length <= 5 * 10^4
1 <= names[i].length <= 20
names[i] consists of lower case English letters, digits and/or round brackets.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/making-file-names-unique
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

看到题目首先想到map
mp[fileName]就是fileName下一个的后缀数
一开始mp中全为0,第一个访问到的name必是没用过的,这时置mp[name]=1,表示name中已经有一个成员了。

但是这种处理方法会产生两个问题
对于sample
w w(1) w w(1)
the correct output should be
w w(1) w(2) w(1)(1)


第二个w发现mp[w]为1,自己应该为w(1)
but there is one file named w(1), so it should be named w(2)
因此在res.push_back()之前必须确保对应mp为0或不存在


第二个w(1)需要为w(1)(1)
因此所有新名字产生后,都要在res中产生新的key,不能仅是最初具有的那些key
如本样例中,最初的简单想法可能为

遇到的fileNamemp[w]mp[w(1)]
init00
w10
w(1)11
w21

很快就会发现这种处理无法正确进行下去。

必须每次产生新的文件名,也要对应产生map中的key。
但不能因为这样就不去更新原来map中的旧值,使得所有元素最大只为1.
如果这样会出现tle
产生新key的同时对于原来map中的值也要更新

代码

对于vector names遍历了两遍,第一遍生成了unordered map

注意产生新的fileName时做了三件事
res.push_back(newName) 得到结果
mp[newName] = 1;
mp[origName]更新

class Solution {
public:
	//用时战胜38%
    vector<string> getFolderNames(vector<string>& names) {
        unordered_map<string, int> mp;
        vector<string> res;
        for(auto name: names){
            mp[name] = 0;
        }
        for(auto name: names){
            if(mp[name] == 0){
                res.push_back(name);
                mp[name]++;
            }else{
                int temp = mp[name];
                while(1){
                    if(mp[name + '(' + to_string(temp) + ')'] == 0){
                        res.push_back(name + '(' + to_string(temp) + ')');
                        mp[name + '(' + to_string(temp) + ')']++;
                        mp[name] = temp + 1;
                        break;
                    }
                    temp++;
                }
            }
        }
        return res;
    }
};

这里注意unordered_map and map之间的巨大时间差异

Internally, the elements in a map are always sorted by its key following a specific strict weak ordering criterion indicated by its internal comparison object (of type Compare).

map containers are generally slower than unordered_map containers to access individual elements by their key, but they allow the direct iteration on subsets based on their order.
使用map获取元素通常比unordered_map更慢
map container introduction

下面是一个用时更短的函数范例

class Solution {
public:
    vector<string> getFolderNames(vector<string>& names) {

        vector<string> res;
        unordered_map<string, int> table;
        for(const string& name: names){
            if(table.count(name)){
                for(int k = table[name] + 1; ; k ++){
                    string new_name = name + "(" + to_string(k) + ")";
                    if(!table.count(new_name)){
                        res.push_back(new_name);
                        table[name] = k; 
                        table[new_name] = 0; // 更新 new_name
                        break;
                    }
                }
            }
            else{
                res.push_back(name);
                table[name] = 0;
            }
        }
        return res;
    }
};

只遍历一遍names
更灵活地使用了std::map::count
Count elements with a specific key
Searches the container for elements with a key equivalent to k and returns the number of matches.

Because all elements in a map container are unique, the function can only return 1 (if the element is found) or zero (otherwise).

Two keys are considered equivalent if the container’s comparison object returns false reflexively (i.e., no matter the order in which the keys are passed as arguments).

得到newName后,同样是做三件事。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值