一、 问题描述:
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 multipleslashes '/' together, such as "/home//foo/".
In this case, you should ignore redundant slashes and return "/home/foo".
二、 问题分析:
给定Unix-style的绝对路径,要求简化路径,找出没有回路或多余路径的最简化路径。
首先,先了解下Unix-style的绝对路径格式:
linux的绝对路径是指从根目录说起的. 例如 /dev/somedir/...
有5个相对路径的表示方法:
1. 当前目录 /.
2. 父目录 /..
3. 指定目录 /filename
4. 某用户的根目录 ~user
5. 自己的根目录 ~
注意:后面两种表示方法本题不会出现
例如,给定 "/a/./b/../../c/":
1、 因为/.表示当前目录,所以忽略这一路径,路径缩减为"/a/b/../../c/";
2、 /..表示父目录,需退回前一个路径,路径缩减为"/a/../c/";
3、 所以最后输出结果为"/c";
另外,需特殊考虑:
1、 当 path = "/../"时,返回路径应为"/";
2、 忽略重复的'/',例如:"/home//foo/",应返回 "/home/foo";
三、 算法设计:
因为路径属于层次性结构,类似递归函数,在一层中指定新的一层,在新的一层中又重复上一层的操作。而又会出现回退一层的情况,这不难和栈(stack)这一数据结构联想在一起:指定新一层等同于压栈操作(push),回退一层等同于弹栈操作(pop),直至再无需要压栈的元素后,路径压缩即完成。
算法描述如下:
给定路径path,定义空字符串str,空列表l,遍历path中的字符ch,进行以下操作:
1 如果ch不为‘/’,则令str = str + ch
2 如果ch为‘/’且str不为空串,则对str进行以下操作:
2.1 如果str为‘.’(当前目录),则仅把str赋值为空字符串
2.2 如果str为‘..’(父目录),若l不为空,则删除l中最后一个元素并把str赋值为空字符串;若l为空,则仅把str赋值为空字符串
2.3 其他情况时,均把str添加进l,并把str赋值为空字符串
3 如果ch为path中最后一个字符,则判断str是否为空,不为空则把str添加进l
最后获得的列表l即为最短绝对路径目录,在每个目录中间加上‘/’后输出即为最终简化后的绝对路径
四、 程序实现:
class Solution:
def simplifyPath(self, path):
"""
:type path: str
:rtype: str
"""
path = list(path)
stack = []
n = len(path)
name = ''
for a in range(n):
if(path[a]=='/' and name!=''):
self.fun(stack, name)
name = ''
elif(path[a]!='/'):
name += path[a]
if(name!=''):
self.fun(stack, name)
s = ''
while(stack):
s = s + '/' + stack[0]
del stack[0]
if(s==''):
s = '/'
return s
def fun(self, stack, name):
if(name=='..'):
if(stack):
stack.pop()
elif(name=='.'):
return
else:
stack.append(name)