[LeetCode] Longest Absolute File Path 最長的絕對檔案路徑
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-directorysubsubdir1
. 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"
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
.
這道題給了我們一個字串,裡面包含\n和\t這種表示回車和空格的特殊字元,讓我們找到某一個最長的絕對檔案路徑,要注意的是,最長絕對檔案路徑不一定是要最深的路徑,我們可以用雜湊表來建立深度和當前深度的絕對路徑長度之間的對映,那麼當前深度下的檔案的絕對路徑就是檔名長度加上雜湊表中當前深度對應的長度,我們的思路是遍歷整個字串,遇到\n或者\t就停下來,然後我們判斷,如果遇到的是回車,我們把這段檔名提取出來,如果裡面包含'.',說明是檔案,我們更新res長度,如果不包含點,說明是資料夾,我們深度level自增1,然後建立當前深度和總長度之間的對映,然後我們將深度level重置為0。之前如果遇到的是空格\t,那麼我們深度加一,通過累加\t的個數,我們可以得知當前檔案或資料夾的深度,然後做對應的處理,參見程式碼如下:
C++ 解法一:
class Solution { public: int lengthLongestPath(string input) { int res = 0, n = input.size(), level = 0; unordered_map<int, int> m {{0, 0}}; for (int i = 0; i < n; ++i) { int start = i; while (i < n && input[i] != '\n' && input[i] != '\t') ++i; if (i >= n || input[i] == '\n') { string t = input.substr(start, i - start); if (t.find('.') != string::npos) { res = max(res, m[level] + (int)t.size()); } else { ++level; m[level] = m[level - 1] + (int)t.size() + 1; } level = 0; } else { ++level; } } return res; } };
下面這種方法用到了字串流機制,通過getline函式可以一行一行的獲取資料,實際上相當於根據回車符\n把每段分割開了,然後對於每一行,我們找最後一個空格符\t的位置,然後可以得到檔案或資料夾的名字,然後我們判斷其是檔案還是資料夾,如果是檔案就更新res,如果是資料夾就更新雜湊表的對映,參見程式碼如下:
C++ 解法二:
class Solution { public: int lengthLongestPath(string input) { int res = 0; istringstream ss(input); unordered_map<int, int> m{{0, 0}}; string line = ""; while (getline(ss, line)) { int level = line.find_last_of('\t') + 1; int len = line.substr(level).size(); if (line.find('.') != string::npos) { res = max(res, m[level] + len); } else { m[level + 1] = m[level] + len + 1; } } return res; } };
Java 解法二:
public class Solution { public int lengthLongestPath(String input) { int res = 0; Map<Integer, Integer> m = new HashMap<>(); m.put(0, 0); for (String s : input.split("\n")) { int level = s.lastIndexOf("\t") + 1; int len = s.substring(level).length(); if (s.contains(".")) { res = Math.max(res, m.get(level) + len); } else { m.put(level + 1, m.get(level) + len + 1); } } return res; } }
參考資料: