Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目概述:
leetcode第71题:简化路径
给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/' 开头),请你将其转化为更加简洁的规范路径。
在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//')都被视为单个斜杠 '/' 。 对于此问题,任何其他格式的点(例如,'...')均被视为文件/目录名称。
请注意,返回的 规范路径 必须遵循下述格式:
- 始终以斜杠 '/' 开头。
- 两个目录名之间必须只有一个斜杠 '/' 。
- 最后一个目录名(如果存在)不能 以 '/' 结尾。
- 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 '.' 或 '..')。 返回简化后得到的 规范路径 。
这道题的题目比较长,简单来说就是把传入路径中的./
和../
按其规则得到正确的path。类似于node中的path.resolve
,主要解决绝对路径和相对路径混用的情况,但是我们这个题目没有path.resolve
复杂。
示例 1:
输入:path = "/a/./b/../../c/"
输出:"/c"
示例 2:
输入:path = "/home/"
输出:"/home"
解释:注意,最后一个目录名后面没有斜杠。
示例 3:
输入:path = "/home//foo/"
输出:"/home/foo"
解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。
二、思路分析:
栈结构的特点:先入后出,后入先出。(可以视为一个有底的桶)
- 这道题也是利用栈的特点
- 对应path我们可以用
/
分割,每一部分的情况可能是空字符串、.
一个点、..
两个点、xxx
正常的路径字符。其中遇到正常的路径字符xxx
时,我们需要入栈,记录下当前的目录。遇到的空、一个点,我们可以直接忽略。..
两个点的情况我们需要返回上级目录,即出栈操作。
三、AC 代码:
/**
* @param {string} path
* @return {string}
*/
var simplifyPath = function(path) {
const stack = []
const pathArr = path.split('/')
for(let i=0; i<pathArr.length;i++){
const p = pathArr[i]
// p为 ''和'.'直接忽略;'..'返回上一级(出栈一个);正常的字符串入栈
if (p==='..') {
stack.pop()
} else if (p&&p!=='.') {
stack.push(p)
}
}
return '/'+stack.join('/')
};
四、总结:
延申:大家可能觉得上面的代码还行,但是当识别判断规则较多时就会产生一大堆的if...else的判断比较丑,且可读性较差。这种情况下那我们可以做一些设计模式:
// 可以将定义和使用分离开
// 定义规则
const obj = {
'': stack=>stack,
'.': stack=>stack,
'..': stack=>{
stack.pop();
return stack;
}
}
var simplifyPath = function(path) {
const stack = []
const pathArr = path.split('/')
for(let i=0; i<pathArr.length;i++){
const p = pathArr[i]
if (p in obj) {
obj[p](stack)
} else {
stack.push(p)
}
}
return '/'+stack.join('/')
};