力扣面试150(43/150)
7.29 71. 简化路径
给你一个字符串 path
,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/'
开头),请你将其转化为 更加简洁的规范路径。
在 Unix 风格的文件系统中规则如下:
- 一个点
'.'
表示当前目录本身。 - 此外,两个点
'..'
表示将目录切换到上一级(指向父目录)。 - 任意多个连续的斜杠(即,
'//'
或'///'
)都被视为单个斜杠'/'
。 - 任何其他格式的点(例如,
'...'
或'....'
)均被视为有效的文件/目录名称。
返回的 简化路径 必须遵循下述格式:
- 始终以斜杠
'/'
开头。 - 两个目录名之间必须只有一个斜杠
'/'
。 - 最后一个目录名(如果存在)不能 以
'/'
结尾。 - 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含
'.'
或'..'
)。
返回简化后得到的 规范路径 。
我的思路:
- 初始化与分割:首先,我将输入路径
path
以'/'
为分隔符进行分割,得到一个指令数组arrPath
。同时,我初始化一个空数组ansArr
作为栈,用于构建最终的规范路径。 - 遍历与处理:遍历
arrPath
中的每一个指令item
:- 情况一:处理上级目录 ‘…’。当遇到
'..'
时,核心逻辑是返回上一级目录。在栈结构中,这对应着一个“出栈”操作:ansArr.pop()
。但这里有一个关键的边界条件需要考虑:如果路径已经处于根目录'/'
,再执行'..'
不应该继续出栈,否则会出错。因此,我的处理逻辑是:只要栈不为空,就执行出栈操作。这能优雅地处理所有情况,包括路径末尾的'..'
。 - 情况二:处理有效目录。对于其他非空且非
'.'
的指令(即有效的目录名),我需要将其“入栈”。我的初始想法是,先向栈中添加一个'/'
,再添加目录名。例如,处理目录名'foo'
时,执行ansArr.push('/', 'foo')
。这个操作确保了路径中目录之间的分隔符是正确的。
- 情况一:处理上级目录 ‘…’。当遇到
在进行pop或者添加’/'的时候,我是直接判断的ansArr[i],我单纯的以为这个就是ansArr的末尾了,其实不是的!
所以我后面直接 let ansLen = ansArr.length;,就解决了bug
我的代码:
/*** @param {string} path* @return {string}*/
var simplifyPath = function(path) {const arrPath = path.split('/');let len = arrPath.length ;let i = 0 ;let ansArr = [];for(i ; i < len ; i++){if(i === len - 1 && arrPath[i] === ''){return ansArr.join('') === '' ? '/' : ansArr.join('');} if(arrPath[i] === '' || arrPath[i] === '.'){continue;}if(arrPath[i] === '..'){ansArr.pop();let ansLen = ansArr.length;if(ansArr[ansLen - 1] === '/'){ansArr.pop();}}else {let ansLen = ansArr.length;if(ansArr[ansLen - 1] !== '/' ){ansArr.push('/');}ansArr.push(arrPath[i]);}}const str = ansArr.join('');return str.length === 0 ? "/" : ansArr.join('');};
我的总结:
该代码使用数组模拟栈,通过分割路径字符串并处理四种情况(空字符串、当前目录’.‘、上级目录’…‘和普通目录名)来构建规范路径。核心逻辑是遇到’…‘时回退一级,遇到普通目录时入栈,并在目录名前添加必要的’/‘。代码处理了路径末尾的’/'和栈为空(即回退到根目录)的边界情况,逻辑清晰且完整。