[Leetcode]71. Simplify Path

[Leetcode]71. Simplify Path
题目链接https://leetcode.com/problems/simplify-path/#/description

这道题一眼望过去好像也不难的样子呢。关键在于知道并理解linux路径结构。然后就是个玩字符串的事情了。

根据题目来总结规律
Given an absolute path for a file (Unix-style), simplify it.
For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
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".
这道题让简化给定的路径,光根据题目中给的那一个例子还真不太好总结出规律,应该再加上两个例子 path = "/a/./b/../c/", => "/a/c"和path = "/a/./b/c/", => "/a/b/c", 这样我们就可以知道中间是"."的情况直接去掉,是".."时删掉它上面挨着的一个路径,而下面的边界条件给的一些情况中可以得知,如果是空的话返回"/",如果有多个"/"只保留一个。那么我们可以把路径看做是由一个或多个"/"分割开的众多子字符串,把它们分别提取出来一一处理即可


这篇的讲解不错,很简洁。 这个是stack解法。看了下,保存结果的都是stack解法,这篇讲的也不错。题目分析明白了,现在第一个难题是如何分割字符串,分割原则就是,有一个或者多个'/' 的,我们要按照一个处理。String.split("/+")应该可以解决这个.分割部分就除了差错,用了String s , s == "."; 这样的比较,如此低级错误简直了,初学者错误啊。String是个class,是不能这样比较内容的。本来想的是,就一个wihle循环,从后往前,因为我的思路是,反正最后一个目录总是不会被搞掉的,所以就从后面来。遇见一个./ 不管,两个../就忽略前一个,别的就写进去最终路径。结果这个方法有逻辑错误,../前面要是还有../就不行了。。。

总之,从后面来这个方法可能是不对的,一开始思路上的不对。因为仔细想想,人家Linux自己解析的时候,估计也是从前往后解析的,毕竟用户是从前往后输入的。目前为止看的所有答案都是先分割,然后用一个指针指向分割后的数组,用stack存放结果数组,如果遇到../就pop()出来stack里面的东西。这也许是解决我上面没有解决的连续跳跃的最有效办法了。因为原理上讲,这个东西就是要处理最近的文件夹名字,也就是说stack比queue更合适。

另外,分割字符串步骤,还有个小坑,要是前面没东西,分割的话就是空字符。需要检查。


看了几个时间短的答案,都是直接在分割好的list里做文章,那ptr指着,不拿出来stack里,还有个时间更短的,直接charAt()一个char一个char来。不太容易想,反正复杂度都是线性的。我们就不说那些了。
AC答案:

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














































Comments

Popular posts from this blog

LeetCode] 644.Maximum Average Subarray II

[Leetcode]375. Guess Number Higher or Lower II

[Leetcode] 643. Maximum Average Subarray I