LeetCode 71. Simplify Path

Zetrue_Li發表於2018-05-16

一、       問題描述:

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       如果chpath中最後一個字元,則判斷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)

相關文章