持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
现在前端很多岗位面试需要有一定的算法基础,或者说经常刷算法的会优先考虑。
因此每天刷刷LeetCode非常有必要
在这之前我也刷过一些算法题,也希望以后也坚持刷,跟某掘友一样,我也想刷穿 LeetCode
一、题目描述
假设有一个同时存储文件和目录的文件系统。下图展示了文件系统的一个示例:
这里将 dir 作为根目录中的唯一目录。dir 包含两个子目录 subdir1 和 subdir2 。subdir1 包含文件 file1.ext 和子目录 subsubdir1;subdir2 包含子目录 subsubdir2,该子目录下包含文件 file2.ext 。
在文本格式中,如下所示(⟶表示制表符):
dir
⟶ subdir1
⟶ ⟶ file1.ext
⟶ ⟶ subsubdir1
⟶ subdir2
⟶ ⟶ subsubdir2
⟶ ⟶ ⟶ file2.ext
如果是代码表示,上面的文件系统可以写为 "dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext" 。'\n' 和 '\t' 分别是换行符和制表符。
文件系统中的每个文件和文件夹都有一个唯一的 绝对路径 ,即必须打开才能到达文件/目录所在位置的目录顺序,所有路径用 '/' 连接。上面例子中,指向 file2.ext 的 绝对路径 是 "dir/subdir2/subsubdir2/file2.ext" 。每个目录名由字母、数字和/或空格组成,每个文件名遵循 name.extension 的格式,其中 name 和 extension由字母、数字和/或空格组成。
给定一个以上述格式表示文件系统的字符串 input
,返回文件系统中 指向 文件 的 最长绝对路径 的长度 。 如果系统中没有文件,返回 0
。
二、思路分析
大致方法:用栈来维护结果字符串的长度,按照层级遍历。
- 首先将字符串通过\n进行分割,返回分割后的数组再处理
- 遍历数组,数组中的某个元素代表文件目录的某个层级,下边需要处理的是每个层级的绝对路径长度
- 当文件在某个层级的时候,其现在的最长文件绝对路径包括现在层级字符串的长度加上前面所有层级字符串的长度,而字符串的长度需要用栈来维护
- 较难处理的是层级的变换,当dir的一个子目录遍历完之后,比如此时在subsubdir1,现在的层级为3,但是subdir1已经遍历结束,下一个文件为subdir2就需要回退到第一级目录,需要改变栈维护的字符串长度。
三、代码实现
/**
* @param {string} input
* @return {number}
*/
const lengthLongestPath = function (input) {
let res = 0
let stack = []
stack.push(0)
let newString = input.split('\n')
for (let i = 0; i < newString.length; i++) {
// 确定当前文件的层级,当没有/t的时候返回-1,说明文件在0级。
// 需要注意的是lastIndexOf
let level = newString[i].lastIndexOf('\t') + 1
/**
* 较难理解的部分
*/
while (stack.length - level > 1) {
stack.pop()
}
// \t\tsubsubdir1 这个字符串的长度为出去\之后的长度,计算length的时候需要减去层数补上1 也就是说长度为subsubdir1/ 这个/是算在字符串长度中的
// 后边的加1表示/这个符号
let length = stack[stack.length - 1] + (newString[i].length - level + 1)
console.log(newString[i])
stack.push(length)
if (newString[i].includes('.')) {
// 这个-1是为了把/这个符号的长度给去掉,因为是最后一个文件所以没/
res = Math.max(res, length - 1)
}
}
return res
};
四、总结
以上就是本道题的所有内容了,本系列会持续更,欢迎点赞、关注、收藏,另外如有其他的问题,欢迎下方留言给我,我会第一时间回复你,感谢~