Problem · Design

In-Memory Filesystem Navigation

Learn this problem
MediumUber logoUberFULLTIMEPHONE SCREEN
See Uber hiring insights

Problem statement

Implement a mutable in-memory directory tree and simulate an ordered array of shell-like commands.

Each command has one of these forms:

  • pwd appends the current directory's canonical absolute path to the result.
  • mkdir PATH creates the final directory named by PATH. The path may be absolute or relative, may contain . and .., contains no wildcard, and its parent already exists. Creating an existing directory is a no-op.
  • cd PATH changes the current directory after resolving the complete path. The path may be absolute or relative and may contain literal directory names, ., .., and *.

An absolute path starts at /; a relative path starts at the current directory. A . segment keeps each current candidate. A .. segment moves each candidate to its parent, while the root stays at the root. A * segment matches exactly one child directory. Multiple wildcard segments therefore support multi-level glob matching.

Every cd pattern matches at least one existing directory. If it matches several directories, choose the one with the lexicographically smallest canonical absolute path. Apply the cd transition atomically after the entire path is resolved.

Return the paths produced by pwd, in command order.

Function

simulateFileSystem(commands: String[]) → String[]

Examples

Example 1

commands = ["mkdir /home","mkdir /home/alice","cd /home/alice","pwd","cd ..","pwd"]return = ["/home/alice","/home"]

The first pwd observes /home/alice. Then .. moves to its parent, so the second result is /home.

Example 2

commands = ["mkdir /teams","mkdir /teams/alpha","mkdir /teams/beta","mkdir /teams/alpha/docs","mkdir /teams/beta/docs","cd /teams/*/docs","pwd","cd .././..","pwd"]return = ["/teams/alpha/docs","/teams"]

The wildcard pattern matches both documentation directories, so lexicographic order selects /teams/alpha/docs. From there, .././.. resolves to /teams.

Example 3

commands = ["mkdir /a","mkdir /a/x","mkdir /a/z","mkdir /a/x/y","mkdir /a/z/y","cd /a","cd */*","pwd","cd ../../..","pwd"]return = ["/a/x/y","/"]

Two relative multi-level matches exist, and /a/x/y is lexicographically smaller. Three parent steps then reach the root, which remains /.

Constraints

  • 1 <= commands.length <= 2000
  • Commands use exactly pwd, mkdir PATH, or cd PATH.
  • Directory names contain 1 to 20 lowercase English letters.
  • Every path is canonical in shape: it has no trailing slash except / and no consecutive slashes.
  • A mkdir path ends in a literal directory name, contains no *, and its parent exists.
  • Every cd path matches at least one existing directory.
  • At most 2000 directories are created, and each path has at most 200 segments.
  • The total length of all command strings is at most 200000.

More Uber problems

drafts saved locally
public String[] simulateFileSystem(String[] commands) {
    // Write your solution here
}
commands["mkdir /home","mkdir /home/alice","cd /home/alice","pwd","cd ..","pwd"]
expected["/home/alice", "/home"]
checking account