原文链接: https://leetcode-cn.com/problems/remove-sub-folders-from-the-filesystem
英文原文
Given a list of folders folder
, return the folders after removing all sub-folders in those folders. You may return the answer in any order.
If a folder[i]
is located within another folder[j]
, it is called a sub-folder of it.
The format of a path is one or more concatenated strings of the form: '/'
followed by one or more lowercase English letters.
- For example,
"/leetcode"
and"/leetcode/problems"
are valid paths while an empty string and"/"
are not.
Example 1:
Input: folder = ["/a","/a/b","/c/d","/c/d/e","/c/f"] Output: ["/a","/c/d","/c/f"] Explanation: Folders "/a/b/" is a subfolder of "/a" and "/c/d/e" is inside of folder "/c/d" in our filesystem.
Example 2:
Input: folder = ["/a","/a/b/c","/a/b/d"] Output: ["/a"] Explanation: Folders "/a/b/c" and "/a/b/d/" will be removed because they are subfolders of "/a".
Example 3:
Input: folder = ["/a/b/c","/a/b/ca","/a/b/d"] Output: ["/a/b/c","/a/b/ca","/a/b/d"]
Constraints:
1 <= folder.length <= 4 * 104
2 <= folder[i].length <= 100
folder[i]
contains only lowercase letters and'/'
.folder[i]
always starts with the character'/'
.- Each folder name is unique.
中文题目
你是一位系统管理员,手里有一份文件夹列表 folder
,你的任务是要删除该列表中的所有 子文件夹,并以 任意顺序 返回剩下的文件夹。
我们这样定义「子文件夹」:
- 如果文件夹
folder[i]
位于另一个文件夹folder[j]
下,那么folder[i]
就是folder[j]
的子文件夹。
文件夹的「路径」是由一个或多个按以下格式串联形成的字符串:
/
后跟一个或者多个小写英文字母。
例如,/leetcode
和 /leetcode/problems
都是有效的路径,而空字符串和 /
不是。
示例 1:
输入:folder = ["/a","/a/b","/c/d","/c/d/e","/c/f"] 输出:["/a","/c/d","/c/f"] 解释:"/a/b/" 是 "/a" 的子文件夹,而 "/c/d/e" 是 "/c/d" 的子文件夹。
示例 2:
输入:folder = ["/a","/a/b/c","/a/b/d"] 输出:["/a"] 解释:文件夹 "/a/b/c" 和 "/a/b/d/" 都会被删除,因为它们都是 "/a" 的子文件夹。
示例 3:
输入:folder = ["/a/b/c","/a/b/d","/a/b/ca"] 输出:["/a/b/c","/a/b/ca","/a/b/d"]
提示:
1 <= folder.length <= 4 * 10^4
2 <= folder[i].length <= 100
folder[i]
只包含小写字母和/
folder[i]
总是以字符/
起始- 每个文件夹名都是唯一的
通过代码
高赞题解
思路:父文件夹是子文件夹的前缀,所以排序后父文件夹一定在子文件前。
因此用一个set记录父文件夹,再比较其后的文件夹的前缀是否有它即可。
class Solution {
public:
vector<string> removeSubfolders(vector<string>& folder) {
sort(folder.begin(),folder.end());
unordered_set<string> father;
vector<string> ans;
for(string s:folder){
string f="/";
bool is=false; //is表示是否为子文件夹
for(int i=1;i<s.size();++i){
if(s[i]=='/'){
if(father.count(f)){ //若前缀在p中则说明z是子文件夹
is=true;
break;
}
f+=s[i];
}
else{
f+=s[i];
}
}
if(is==false){
father.insert(s);
ans.push_back(s);
}
}
return ans;
}
};
改进:
又因为排序后,父文件夹和其子文件夹必定是连续排列的,所以若一个文件夹不是上一个父文件夹的子文件夹,那它自己就是一个父文件夹
class Solution {
public:
vector<string> removeSubfolders(vector<string>& folder) {
sort(folder.begin(),folder.end());
vector<string> ans;
ans.push_back(folder[0]);
for(int i=1;i<folder.size();++i){
string father=ans.back()+"/",cur=folder[i]; //这里father+"/"是为了避免 将 /a/bc 视为 /a/b的子文件夹
if(cur.find(father)==cur.npos){
ans.push_back(cur);
}
}
return ans;
}
};
统计信息
通过次数 | 提交次数 | AC比率 |
---|---|---|
8469 | 17429 | 48.6% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|