[Leetcode] - Simplify Path

Given an absolute path for a file (Unix-style), simplify it.

For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"

click to show corner cases.

Corner Cases:

  • Did you consider the case where path = "/../"?
    In this case, you should return "/".
  • Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/".
    In this case, you should ignore redundant slashes and return "/home/foo".

本來覺得這種題不是很重要,剛纔跑步的時候看到LY,說他去Google on site的時候考了這道題,於是趕緊回來複習一下。

基本思路是這樣的,用一個stack來記錄有效的路徑。注意,壓入stack的有效路徑無需加上"/",在最後出棧的時候補上就行了。這樣做可以將問題簡化不少。

首先,把原字符串對於"/"進行split,得到一個字符串數組。然後依次遍歷這個數組中的每個元素,會有如下幾種情況出現:

1. 當前字符串是"."或者爲空。在Linux中,一個點代表當前目錄,而空字符串則意味着兩個斜槓相鄰。遇到這兩種情況,直接continue,因爲他們不會對有效路徑造成任何影響。

2. 當前字符串是".."。同樣,Linux的路徑中兩個連續的點意味着返回上級目錄。所以此時,如果棧不爲空,則pop出棧頂元素。若棧爲空,則continue。

3. 當前字符串是其它。這意味着該字符串爲一個目錄或文件名,所以我們應該將其push到stack中,作爲有效路徑的一部分。

在遍歷字符串數組的所有元素之後,我們可以用一個StringBuilder來建立有效路徑。具體的方法是這樣的,依次將棧的每個元素pop出來,插入StringBuilder的第一個位置,然後在每兩個棧內元素之間,加入一個斜槓,直到棧爲空。值得注意的是,如果一開始棧就爲空,那麼直接返回一個斜槓,這種情況相當於Corner Case中的第一種情況。


代碼如下:

public class Solution {
    public String simplifyPath(String path) {
        if(path==null) return null;
        
        String[] files = path.split("/");
        Stack<String> stack = new Stack<String>();
        for(int i=0; i<files.length; i++) {
            if(files[i].equals(".") || files[i].equals("")) {
                continue;
            }
            else if(files[i].equals("..")) {
                if(!stack.isEmpty()) stack.pop();
            }
            else {
                stack.push(files[i]);
            }
        }
        
        StringBuilder res = new StringBuilder();
        if(stack.isEmpty()) return "/";
        else {
            while(!stack.isEmpty()) {
                res.insert(0, stack.pop());
                res.insert(0, "/");
            }
        }
        return res.toString();
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章