这道题和罗马数字转换一样,题目的求解方法与背景联系地非常强。基本上的一些规则是,如果遇到.或者“”,就直接跳过;如果遇到..就将上面的一个路径回退。所以根据上面的思想,我们首先用一个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构造函数的参数使用