题目:
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"
.
题意:
给定一个绝对路径(Unix-style),简化它.
比如:
path = "/home/"
, => "/home"
path = "/a/./b/../../c/"
, => "/c"
个别情况:
1. 你是否考虑过例子path = "/../"
? 这时你需要返回 "/"
.
2. 另外一种特别的情况是含有重复的'/'
,比如"/home//foo/"
. 这时你需要返回重复的部分,返回"/home/foo"
.
算法分析:
*思路比较明确,就是维护一个栈,对于每一个块(以/作为分界)进行分析,
* 如果遇到..则表示要上一层,那么就是进行出栈操作,
* 如果遇到.则是停留当前,直接跳过,
* 其他文件路径则直接进栈即可。
* 最后根据栈中的内容转换成路径即可(这里是把栈转成数组,然后依次添加)。
* 当对所有分割成的字符串都处理完后,检查第一个栈是否为空,如果栈为空,则证明没有可以重建的目录名,返回"/"即可。
* 当第一个栈不为空时,这时候我们需要还原path.所以这里我应用了第二个栈,先将第一个栈元素弹出入栈到第二个栈,然后再利用第二个栈还原回初始path
AC代码:
public class Solution
{
public String simplifyPath(String path)
{
if(path == null||path.length()==0)
return path;
Stack<String> stack = new Stack<String>();
String[] list = path.split("/");
for(int i=0; i<list.length; i++)
{
if(list[i].equals(".")||list[i].length()==0)//如果遇到.则是停留当前,直接跳过
continue;
else if(!list[i].equals(".."))//其他文件路径则直接进栈即可
stack.push(list[i]);
else
{
if(!stack.isEmpty())//如果遇到..则表示要上一层,那么就是进行出栈操作
stack.pop();
}
}
StringBuilder res = new StringBuilder();
Stack<String> temp = new Stack<String>();
while(!stack.isEmpty())
temp.push(stack.pop());//原始path是/a/b/c/,栈里的顺序是:a b c,如果依次弹栈还原的话是:/c/b/a(错误!),正确答案为:/a/b/c
while(!temp.isEmpty())
res.append("/"+temp.pop());
if(res.length()==0)//如果栈为空,则证明没有可以重建的目录名,返回"/"即可
res.append("/");
return res.toString();
}
}