這道題和羅馬數字轉換一樣,題目的求解方法與背景聯繫地非常強。基本上的一些規則是,如果遇到.或者“”,就直接跳過;如果遇到..就將上面的一個路徑回退。所以根據上面的思想,我們首先用一個Stack存儲結果路徑中的元素,使用一個Set存儲..,. 和“”這種需要跳過的特殊字符,然後將題目中給出的String以/逐個分割開來進行掃描,可能的情況如下:
如果遇到..且Stack不爲空的話,那麼回退Stack中的一個元素,如果爲空則直接跳過;
如果遇到.和/的話則直接跳過;
如果遇到其他有意義的字符就加入到Stack裏面;
掃描完所有的元素之後,這時Stack中存儲了結果路徑中的所有元素,只要將它們添加並且使用/逐個分割即可,代碼如下:
public class Solution {
public String simplifyPath(String path) {
Deque<String> stack = new LinkedList<>();
Set<String> skip = new HashSet<>(Arrays.asList("..", ".", ""));
for(String dir : path.split("/")){
if(dir.equals("..") && !stack.isEmpty()) stack.pop();
else if(!skip.contains(dir)) stack.push(dir);
}
String result = "";
for(String dir : stack) result = "/" + dir + result;
return result.isEmpty() ? "/" : result;
}
}
知識點:
1. 另外這道題目中還有一些非常值得學習的Java知識:
Deque<E>是Java中的一個接口,意思爲double ended queue,它是一個線性的Collection,支持在兩端插入和刪除元素。因爲Deque是一個接口,所以不能對它進行實例化,需要使用實現了Deque這個接口的類:ArrayDeque, ConcurrentLinkedDeque, LinkedBlockingDeque, LinkedList,它的一些方法如下圖
2. Arrays.asList方法,返回一個固定大小的List<T>,而它是一個Collection,所以可以作爲HashSet構造函數的參數使用