Suppose we abstract our file system by a string in the following manner:
The string
"dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext" represents:dir
subdir1
subdir2
file.ext
The directory
dir contains an empty sub-directory subdir1 and a sub-directory subdir2 containing a file file.ext.
The string
"dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext" represents:dir
subdir1
file1.ext
subsubdir1
subdir2
subsubdir2
file2.ext
The directory
dir contains two sub-directories subdir1 and subdir2. subdir1 contains a file file1.ext and an empty second-level sub-directory subsubdir1. subdir2 contains a second-level sub-directory subsubdir2 containing a file file2.ext.
We are interested in finding the longest (number of characters) absolute path to a file within our file system. For example, in the second example above, the longest absolute path is
"dir/subdir2/subsubdir2/file2.ext", and its length is 32 (not including the double quotes).
Given a string representing the file system in the above format, return the length of the longest absolute path to file in the abstracted file system. If there is no file in the system, return
0.
Note:
- The name of a file contains at least a
.and an extension. - The name of a directory or sub-directory will not contain a
..
Time complexity required:
O(n) where n is the size of the input string.
Notice that
a/aa/aaa/file1.txt is not the longest file path, if there is another path aaaaaaaaaaaaaaaaaaaaa/sth.png.I solved this problem about 7 months ago - when I first started to tackle these Leetcode problems. Back then, I wasn't proficient in any algorithms. But somehow, I managed to solve this problem with an extremely messy code. Ever since I got that job offer, I thought I should re-do some of the problems or focus those problems that require some modeling (i.e., Google problems).
This problem is on the easier side of this kind. It is very obvious files and folders are organized in tree structure. Only if we have a well-organized tree structure, then we can basically use backtracking to find out the answers. However, the input is a string. But, by looking at the string, we can see that the number of '\t' in the element is the same as the level of that elements. For example, '\tsubdir1', '\t\tfile.txt' are in the first, second level of the file organization, respectively.
We can't easily do a tree traverse on this type of string input, but hey, the elements order after input.split('\n') is similar to the in-order traversal of the directory tree (here might be a forest).
Therefore, the abstraction of the problem will be:
Given the in-order traversal of a tree and each element's level, reconstruct the maximum length path from root to leaf where we only considers those leaves that contain '.' (file).Well, then we just use a stack, when the level is higher than the current level, meaning that the incoming element will be the children of current element; when lower, meaning that the incoming one is the parent; the same, siblings.
class Solution(object): def lengthLongestPath(self, input): """ :type input: str :rtype: int """ stack = [] current_level = 0 res = 0 for name in input.split('\n'): #print stack, current_level tabs = name.split('\t') if len(tabs) - 1 == current_level: if stack: stack.pop() stack.append(tabs[-1]) elif len(tabs) -1 > current_level: stack.append(tabs[-1]) else: for _ in range(current_level - len(tabs) + 2): if stack: stack.pop() stack.append(tabs[-1]) if '.' in tabs[-1]: res = max(res, len('/'.join(stack))) current_level = len(tabs) - 1 return res
