设计文件系统
https://leetcode-cn.com/problems/design-file-system/
1166. 设计文件系统
你需要设计一个能提供下面两个函数的文件系统:
create(path, value): 创建一个新的路径,并尽可能将值 value 与路径 path 关联,然后返回 True。如果路径已经存在或者路径的父路径不存在,则返回 False。
get(path): 返回与路径关联的值。如果路径不存在,则返回 -1。
“路径” 是由一个或多个符合下述格式的字符串连接起来形成的:在 / 后跟着一个或多个小写英文字母。
例如 /leetcode 和 /leetcode/problems 都是有效的路径,但空字符串和 / 不是有效的路径。
好了,接下来就请你来实现这两个函数吧!(请参考示例以获得更多信息)
示例 1:
输入:
["FileSystem","create","get"]
[[],["/a",1],["/a"]]
输出:
[null,true,1]
解释:
FileSystem fileSystem = new FileSystem();
fileSystem.create("/a", 1); // 返回 true
fileSystem.get("/a"); // 返回 1
示例 2:
输入:
["FileSystem","create","create","get","create","get"]
[[],["/leet",1],["/leet/code",2],["/leet/code"],["/c/d",1],["/c"]]
输出:
[null,true,true,2,false,-1]
解释:
FileSystem fileSystem = new FileSystem();
fileSystem.create("/leet", 1); // 返回 true
fileSystem.create("/leet/code", 2); // 返回 true
fileSystem.get("/leet/code"); // 返回 2
fileSystem.create("/c/d", 1); // 返回 false 因为父路径 "/c" 不存在。
fileSystem.get("/c"); // 返回 -1 因为该路径不存在。
错误解法:
class FileSystem { public: FileSystem() { } bool createPath(string path, int value) { // 路径合法 if (!isLegualPath(path)) return false; // 路径是否存在 auto tmp = m_pool.find(path); if (tmp != m_pool.end()) return false; //插入 m_pool.insert(make_pair(path, value)); return true; } int get(string path) { // 路径合法 if (!isLegualPath(path)) return false; // 路径是否存在 auto tmp = m_pool.find(path); if (tmp != m_pool.end()) return tmp->second; return -1; } bool isLegualPath(string path) { bool ret = false; // '/'开头,后面至少一个小写字母 int pos = 0; while(path.substr(pos, path.size()-1).find('/') != std::string::npos) { ret = true; if (path[pos+1] < 'a' || path[pos+1] > 'z') { return false; } pos = pos + 1; } return ret; } //存储路径 map<string, int> m_pool; };
花了太多时间在保证输入合法性上,其实这只是次要的。而且对于第二个用例就不过了。
看了一个很高效的解法:
class FileSystem { public: FileSystem() = default; bool createPath(string path, int value) { if (path == "/" || path.empty()) { return false; } auto pos = path.rfind("/"); if (pos == std::string::npos) { return false; } if (pos != 0) { // 说明不只有一个 '/' auto prefix = path.substr(0, pos); if (paths_.find(prefix) == paths_.end()) { return false; } } return paths_.insert(make_pair(path, value)); } int get(string path) { auto iter = paths_.find(path); if (iter == paths_.end()) { return -1; } return iter->second; } private: std::map<std::string, int> paths_; };
其中,使用了rfind() 从后向前搜索,巧妙的解决了后面子目录依赖前面目录是否存在的问题。

浙公网安备 33010602011771号