Remove Sub-Folders from the Filesystem
MedPrompt
Given a list of folders folder, return the folders after removing all sub-folders in those folders. You may return the answer in any order.
If a folder[i] is located within another folder[j], it is called a sub-folder of it. A sub-folder of folder[j] must start with folder[j], followed by a "/". For example, "/a/b" is a sub-folder of "/a", but "/b" is not a sub-folder of "/a/b/c".
The format of a path is one or more concatenated strings of the form: '/' followed by one or more lowercase English letters.
- For example,
"/leetcode"and"/leetcode/problems"are valid paths while an empty string and"/"are not.
Example 1:
Input: folder = ["/a","/a/b","/c/d","/c/d/e","/c/f"]
Output: ["/a","/c/d","/c/f"]
Explanation: Folders "/a/b" is a subfolder of "/a" and "/c/d/e" is inside of folder "/c/d" in our filesystem.Example 2:
Input: folder = ["/a","/a/b/c","/a/b/d"]
Output: ["/a"]
Explanation: Folders "/a/b/c" and "/a/b/d" will be removed because they are subfolders of "/a".Example 3:
Input: folder = ["/a/b/c","/a/b/ca","/a/b/d"]
Output: ["/a/b/c","/a/b/ca","/a/b/d"]
Constraints:
1 <= folder.length <= 4 * 1042 <= folder[i].length <= 100folder[i]contains only lowercase letters and'/'.folder[i]always starts with the character'/'.- Each folder name is unique.
Approaches
3 approaches with complexity analysis and trade-offs.
This approach uses nested loops to compare every folder path against every other folder path. For each pair of folders, it checks if one is a sub-folder of the other. A boolean array is used to mark folders that are identified as sub-folders. Finally, it collects all folders that were not marked.
Algorithm
- Create a boolean array
isSubfolderof the same size as the inputfolderarray, initialized tofalse. - Iterate through the
folderarray with an outer loop (indexi). - Iterate through the
folderarray with an inner loop (indexj). - If
iandjare the same, skip the comparison. - Check if
folder[i]is a sub-folder offolder[j]. A folder is a sub-folder if its path starts with the other folder's path followed by a/. This can be checked usingfolder[i].startsWith(folder[j] + "/"). - If it is a sub-folder, mark
isSubfolder[i]astrueand break the inner loop, as we've confirmedfolder[i]should be removed. - After the loops complete, iterate through the
isSubfolderarray. - If
isSubfolder[k]isfalse, it meansfolder[k]is not a sub-folder of any other folder, so add it to the result list. - Return the result list.
Walkthrough
The brute-force method is the most straightforward way to solve the problem. We take each folder and compare it with all other folders in the list. To check if folderA is a sub-folder of folderB, we verify if the string folderA starts with the string folderB immediately followed by a forward slash '/'. We use an auxiliary boolean array, isSubfolder, to keep track of which folders need to be removed. If we find that folder[i] is a sub-folder of folder[j], we set isSubfolder[i] to true and can stop checking folder[i] against other folders. After all comparisons are done, we construct our final list by including only those folders for which the corresponding isSubfolder flag is false.
import java.util.ArrayList;import java.util.List; class Solution { public List<String> removeSubfolders(String[] folder) { int n = folder.length; boolean[] isSubfolder = new boolean[n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i == j) continue; // Check if folder[i] is a subfolder of folder[j] if (folder[i].startsWith(folder[j] + "/")) { isSubfolder[i] = true; break; // Found its parent, no need to check further } } } List<String> result = new ArrayList<>(); for (int i = 0; i < n; i++) { if (!isSubfolder[i]) { result.add(folder[i]); } } return result; }}Complexity
Time
O(N^2 * L), where N is the number of folders and L is the maximum length of a folder path. The nested loops give a factor of N^2, and the `startsWith` string operation takes O(L) time.
Space
O(N * L), where N is the number of folders and L is the maximum length of a folder path. The boolean array takes O(N) space. The result list can store up to N folders, each of length up to L, resulting in O(N * L) space in the worst case.
Trade-offs
Pros
Simple to understand and implement without requiring complex data structures.
Cons
Highly inefficient due to the O(N^2) complexity, which will likely result in a 'Time Limit Exceeded' error for large inputs.
Solutions
Solution
class Solution {public List<String> removeSubfolders(String[] folder) { Arrays.sort(folder); List<String> ans = new ArrayList<>(); ans.add(folder[0]); for (int i = 1; i < folder.length; ++i) { int m = ans.get(ans.size() - 1).length(); int n = folder[i].length(); if (m >= n || !(ans.get(ans.size() - 1).equals(folder[i].substring(0, m)) && folder[i].charAt(m) == '/')) { ans.add(folder[i]); } } return ans; }}Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.