Problem
Suppose we represent our file system as a string. For example, the string "user\n\tpictures\n\tdocuments\n\t\tnotes.txt" represents:
user
pictures
documents
notes.txtThe directory user contains an empty sub-directory pictures and a sub-directory documents containing a file notes.txt.
The string "user\n\tpictures\n\t\tphoto.png\n\t\tcamera\n\tdocuments\n\t\tlectures\n\t\t\tnotes.txt" represents:
user
pictures
photo.png
camera
documents
lectures
notes.txtThe directory user contains two sub-directories pictures and documents. pictures contains a file photo.png and an empty second-level sub-directory camera. documents contains a second-level sub-directory lectures containing a file notes.txt.
We want to find the longest (as determined by the number of characters) absolute path to a file within our system. For example, in the second example above, the longest absolute path is "user/documents/lectures/notes.txt", and its length is 33 (not including the double quotes).
Given a string representing the file system in this format, return the length of the longest absolute path to a file in the abstracted file system. If there is not a file in the file system, return 0.
Notes:
- Due to system limitations, test cases use form feeds (
'\f', ASCII code12) instead of newline characters. - File names do not contain spaces at the beginning.
Example
For fileSystem = "user\f\tpictures\f\tdocuments\f\t\tnotes.txt", the output should besolution(fileSystem) = 24.
The longest path is "user/documents/notes.txt", and it consists of 24 characters.
Constraints
File system in the format described above. It is guaranteed that:
- the name of a file contains at least a
.and an extension; - the name of a directory or sub-directory does not contain a
..
Note: Due to system limitations, newline characters are given as form feeds ('\f', ASCII code 12) in our test cases.
Guaranteed constraints:1 ≤ fileSystem.length ≤ 6310.
Solution
import "strings"
func solution(fileSystem string) int {
lines := strings.Split(fileSystem, "\f")
stack := []string{}
maxLen := 0
for _, line := range lines {
tabs := strings.Count(line, "\t")
// trim \t to get name
name := strings.TrimLeft(line, "\t")
for len(stack) > tabs {
stack = stack[:len(stack)-1] // pop stack
}
if strings.Contains(name, ".") {
currLen := len(strings.Join(append(stack, name), "/"))
if currLen > maxLen {
maxLen = currLen
}
} else {
stack = append(stack, name)
}
}
return maxLen
}