Java Solution, File class


  • 8
    public class FileSystem {
        class File {
            boolean isFile = false;
            Map<String, File> children = new HashMap<>();
            String content = "";
        }
        
        File root = null;
        
        public FileSystem() {
            root = new File();
        }
        
        public List<String> ls(String path) {
            String[] dirs = path.split("/");
            File node = root;
            List<String> result = new ArrayList<>();
            String name = "";
            for (String dir : dirs) {
                if (dir.length() == 0) continue;
                if (!node.children.containsKey(dir)) {
                    return result;
                }
                node = node.children.get(dir);
                name = dir;
            }
            
            if (node.isFile) {
                result.add(name);
            }
            else {
                for (String key : node.children.keySet()) {
                    result.add(key);
                }
            }
            
            Collections.sort(result);
            
            return result;
        }
        
        public void mkdir(String path) {
            String[] dirs = path.split("/");
            File node = root;
            for (String dir : dirs) {
                if (dir.length() == 0) continue;
                if (!node.children.containsKey(dir)) {
                    File file = new File();
                    node.children.put(dir, file);
                }
                node = node.children.get(dir);
            }
        }
        
        public void addContentToFile(String filePath, String content) {
            String[] dirs = filePath.split("/");
            File node = root;
            for (String dir : dirs) {
                if (dir.length() == 0) continue;
                if (!node.children.containsKey(dir)) {
                    File file = new File();
                    node.children.put(dir, file);
                }
                node = node.children.get(dir);
            }
            node.isFile = true;
            node.content += content;
        }
        
        public String readContentFromFile(String filePath) {
            String[] dirs = filePath.split("/");
            File node = root;
            for (String dir : dirs) {
                if (dir.length() == 0) continue;
                if (!node.children.containsKey(dir)) {
                    File file = new File();
                    node.children.put(dir, file);
                }
                node = node.children.get(dir);
            }
    
            return node.content;
        }
    }
    

  • 3
    I

    Moving some common code to a function (traverse) and using TreeMap instead of HashMap to avoid sorting list every time ls is called.

    public class FileSystem {
        
        Node root;
        
        public FileSystem() {
            root = new Node("/");
        }
        
        public List<String> ls(String path) {
            
            Node nd = traverse(path);
            
            List<String> res = new ArrayList<String>();
            
            if(nd.isFile)
            {
                res.add(nd.name);
            }
            else
            {
                for(String child : nd.children.keySet())
                {
                     res.add(child);   
                }
            }
            
            return res;
        }
        
        public void mkdir(String path) {
            
            traverse(path);
        }
        
        public void addContentToFile(String filePath, String content) {
            
            Node nd = traverse(filePath);
            nd.isFile = true;
            nd.content.append(content);
        }
        
        public String readContentFromFile(String filePath) {
            
            Node nd = traverse(filePath);
            return nd.content.toString();
        }
        
        private Node traverse(String filePath)
        {
            String[] arr = filePath.split("/");
            Node curr = root;
            
            // start from index 1 as 0th element is ""
            for(int i = 1; i < arr.length; i++)
            {
                if(!curr.children.containsKey(arr[i]))
                {
                    Node nd = new Node(arr[i]);
                    curr.children.put(arr[i], nd);
                }
                
                curr = curr.children.get(arr[i]);
            }
            
            return curr;
        }
        
        public class Node
        {
            String name;
            boolean isFile;
            StringBuilder content;
            Map<String, Node> children;
            
            public Node(String name)
            {
                this.content = new StringBuilder();
                this.name = name;
                this.children = new TreeMap<String, Node>();
            }
        }
    }

  • 0
    public class FileSystem {
    
        private Map<String, Set<String>> dirMap = new HashMap<>();
        private Map<String, String> contentMap = new HashMap<>();
        private Comparator<String> comparator = (a, b) -> { 
        	if (a.contains(b) && !a.equals(b)) return 1;
            if (b.contains(a) && !a.equals(b)) return -1;
            return a.compareTo (b);
        };
        
        public FileSystem() {
            dirMap.put ("/", new TreeSet<>(comparator));
        }
        
        public List<String> ls(String path) {
        	List<String> ans = new ArrayList<>();
        	if (contentMap.containsKey(path)) return Arrays.asList(path.substring(path.lastIndexOf("/") + 1));
        	for (String dir : dirMap.getOrDefault (path, new TreeSet<>(comparator))) 
        		ans.add(dir.substring(path.length() + (path.charAt(path.length() - 1) == '/' ? 0 : 1)));
        	return ans;
        }
        
        public void mkdir(String path) {
            String prev = "/";
            for (int idx = 1; idx <= path.length(); idx ++) {
                if (idx == path.length() || path.charAt (idx) == '/') {
                    String dir = path.substring (0, idx); 
                    dirMap.computeIfAbsent (prev, k -> new TreeSet<>(comparator)).add (dir);
                    prev = dir;
                }
            }
            dirMap.putIfAbsent (path, new TreeSet<>(comparator));
        }
        
        public void addContentToFile(String filePath, String content) {
        	mkdir(filePath);
            contentMap.put (filePath, contentMap.getOrDefault (filePath, "") + content);
        }
        
        public String readContentFromFile(String filePath) {
            return contentMap.getOrDefault (filePath, "");
        }
    }
    

  • 0
    R
    This post is deleted!

  • 0
    P

    @invincible How is treemap helpful over a hashmap here? I do not see any ordering required for directories.


  • 0
    F

    amazing solution!


  • 0

    C++ implementation easy to understand

    class FileSystem {
    class TrieNode{
    public:
        map<string, TrieNode*> dict;  //used map to store the directory names in lexicographical order
        bool isFile;
        string content;
        TrieNode(){
            isFile=false;
            content="";
        }
    };
        
    public:
        FileSystem() {
            root = new TrieNode();
        }
        
        vector<string> ls(string path) {
            vector<string> res;
            vector<string> temp = getabbr(path);
            TrieNode* curr = root;
            
            for (auto& ele: temp){
                curr = curr->dict[ele];
            }
            
            if (curr->isFile){
                res.push_back(temp.back());
            }else{
                for (auto& ele: curr->dict){
                    res.push_back(ele.first);
                }
            }
            return res;
        }
        
        void mkdir(string path) {
            createPath(path);
        }
        
        void addContentToFile(string filePath, string content) {
            TrieNode* curr = createPath(filePath);
            curr->isFile = true;
            curr->content += content;
        }
        
        string readContentFromFile(string filePath) {
            TrieNode* curr = createPath(filePath);
            return curr->content;
        }
        
    private:
        TrieNode* root;
        
        vector<string> getabbr(string& path){
            vector<string> res;
            string temp;
            istringstream ss(path);
            while (getline(ss, temp, '/')){
                if (temp != "")
                    res.push_back(temp);
            }
            return res;
        }
        
        TrieNode* createPath(string& path){
            vector<string> temp = getabbr(path);
            TrieNode* curr = root;
            for (auto& ele: temp){
                if (!curr->dict.count(ele))
                    curr->dict[ele] = new TrieNode();
                curr = curr->dict[ele];
            }
            return curr;
        }
    };
    

Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.