diff --git "a/Index/\345\223\210\345\270\214\350\241\250.md" "b/Index/\345\223\210\345\270\214\350\241\250.md" index 575feda5..1918be1b 100644 --- "a/Index/\345\223\210\345\270\214\350\241\250.md" +++ "b/Index/\345\223\210\345\270\214\350\241\250.md" @@ -17,6 +17,7 @@ | [268. 丢失的数字](https://leetcode-cn.com/problems/missing-number/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/missing-number/solution/gong-shui-san-xie-yi-ti-wu-jie-pai-xu-ji-te3s/) | 简单 | 🤩🤩🤩🤩 | | [299. 猜数字游戏](https://leetcode-cn.com/problems/bulls-and-cows/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/bulls-and-cows/solution/gong-shui-san-xie-jian-dan-mo-ni-ti-by-a-tdhs/) | 中等 | 🤩🤩🤩🤩 | | [380. O(1) 时间插入、删除和获取随机元素](https://leetcode-cn.com/problems/insert-delete-getrandom-o1/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/insert-delete-getrandom-o1/solution/by-ac_oier-tpex/) | 中等 | 🤩🤩🤩🤩🤩 | +| [388. 文件的最长绝对路径](https://leetcode-cn.com/problems/longest-absolute-file-path/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-absolute-file-path/solution/by-ac_oier-c55t/) | 中等 | 🤩🤩🤩🤩🤩 | | [318. 最大单词长度乘积](https://leetcode-cn.com/problems/maximum-product-of-word-lengths/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximum-product-of-word-lengths/solution/gong-shui-san-xie-jian-dan-wei-yun-suan-cqtxq/) | 中等 | 🤩🤩🤩🤩 | | [432. 全 O(1) 的数据结构](https://leetcode-cn.com/problems/all-oone-data-structure/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/all-oone-data-structure/solution/by-ac_oier-t26d/) | 困难 | 🤩🤩🤩 | | [447. 回旋镖的数量](https://leetcode-cn.com/problems/number-of-boomerangs/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/number-of-boomerangs/solution/gong-shui-san-xie-shu-ju-jie-gou-yun-yon-evu2/) | 中等 | 🤩🤩🤩🤩 | diff --git "a/Index/\346\250\241\346\213\237.md" "b/Index/\346\250\241\346\213\237.md" index 8ecdf824..b1f83f9a 100644 --- "a/Index/\346\250\241\346\213\237.md" +++ "b/Index/\346\250\241\346\213\237.md" @@ -41,6 +41,7 @@ | [382. 链表随机节点](https://leetcode-cn.com/problems/linked-list-random-node/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/linked-list-random-node/solution/gong-shui-san-xie-xu-shui-chi-chou-yang-1lp9d/) | 中等 | 🤩🤩🤩🤩🤩 | | [383. 赎金信](https://leetcode-cn.com/problems/ransom-note/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/ransom-note/solution/gong-shui-san-xie-jian-dan-ji-shu-mo-ni-udpzn/) | 简单 | 🤩🤩🤩🤩🤩 | | [385. 迷你语法分析器](https://leetcode-cn.com/problems/mini-parser/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/mini-parser/solution/by-ac_oier-zuy6/) | 中等 | 🤩🤩🤩🤩🤩 | +| [388. 文件的最长绝对路径](https://leetcode-cn.com/problems/longest-absolute-file-path/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-absolute-file-path/solution/by-ac_oier-c55t/) | 中等 | 🤩🤩🤩🤩🤩 | | [393. UTF-8 编码验证](https://leetcode-cn.com/problems/utf-8-validation/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/utf-8-validation/solution/by-ac_oier-zvoy/) | 中等 | 🤩🤩🤩🤩🤩 | | [400. 第 N 位数字](https://leetcode-cn.com/problems/nth-digit/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/nth-digit/solution/gong-shui-san-xie-jian-dan-mo-ni-ti-by-a-w5wl/) | 中等 | 🤩🤩🤩🤩 | | [405. 数字转换为十六进制数](https://leetcode-cn.com/problems/convert-a-number-to-hexadecimal/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/convert-a-number-to-hexadecimal/solution/gong-shui-san-xie-yi-ti-shuang-jie-jin-z-d93o/) | 简单 | 🤩🤩🤩🤩 | diff --git "a/LeetCode/381-390/388. \346\226\207\344\273\266\347\232\204\346\234\200\351\225\277\347\273\235\345\257\271\350\267\257\345\276\204\357\274\210\344\270\255\347\255\211\357\274\211.md" "b/LeetCode/381-390/388. \346\226\207\344\273\266\347\232\204\346\234\200\351\225\277\347\273\235\345\257\271\350\267\257\345\276\204\357\274\210\344\270\255\347\255\211\357\274\211.md" new file mode 100644 index 00000000..c4ece329 --- /dev/null +++ "b/LeetCode/381-390/388. \346\226\207\344\273\266\347\232\204\346\234\200\351\225\277\347\273\235\345\257\271\350\267\257\345\276\204\357\274\210\344\270\255\347\255\211\357\274\211.md" @@ -0,0 +1,162 @@ +### 题目描述 + +这是 LeetCode 上的 **[388. 文件的最长绝对路径](https://leetcode-cn.com/problems/longest-absolute-file-path/solution/by-ac_oier-c55t/)** ,难度为 **中等**。 + +Tag : 「模拟」、「哈希表」 + + + +假设有一个同时存储文件和目录的文件系统。下图展示了文件系统的一个示例: + +![](https://assets.leetcode.com/uploads/2020/08/28/mdir.jpg) + +这里将 `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$。 + +示例 1: +![](https://assets.leetcode.com/uploads/2020/08/28/dir1.jpg) +``` +输入:input = "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext" + +输出:20 + +解释:只有一个文件,绝对路径为 "dir/subdir2/file.ext" ,路径长度 20 +``` +示例 2: +![](https://assets.leetcode.com/uploads/2020/08/28/dir2.jpg) +``` +输入:input = "dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext" + +输出:32 + +解释:存在两个文件: +"dir/subdir1/file1.ext" ,路径长度 21 +"dir/subdir2/subsubdir2/file2.ext" ,路径长度 32 +返回 32 ,因为这是最长的路径 +``` +示例 3: +``` +输入:input = "a" + +输出:0 + +解释:不存在任何文件 +``` +示例 4: +``` +输入:input = "file1.txt\nfile2.txt\nlongfile.txt" + +输出:12 + +解释:根目录下有 3 个文件。 +因为根目录中任何东西的绝对路径只是名称本身,所以答案是 "longfile.txt" ,路径长度为 12 +``` + +提示: +* $1 <= input.length <= 10^4$ +* `input` 可能包含小写或大写的英文字母,一个换行符 `'\n'`,一个制表符 `'\t'`,一个点 `'.'`,一个空格 `' '`,和数字。 + +--- + +### 模拟 + 哈希表 + +为了方便,我们将 `input` 替换为 `s`。 + +对于每一个文件或文件夹而言,我们可以通过访问到结尾(`\n`)的方式取得,记为 `cur`,然后根据 `cur` 前面有多少个 `\t` 得知其所在的层级,假设当前其所在层级为 `level`,那么它自然归属到最新一个层级为 `level - 1` 的文件夹中,因此我们可以使用哈希表记录每个层级最新的文件夹路径,通过字符串拼接的方式得到 `cur` 所在的完整路径 `path`,并在处理整个 `s` 过程中,统计长度最大的文件路径。 + +代码: +```Java +class Solution { + public int lengthLongestPath(String s) { + Map map = new HashMap<>(); + int n = s.length(); + String ans = null; + for (int i = 0; i < n; ) { + int level = 0; + while (i < n && s.charAt(i) == '\t' && ++level >= 0) i++; + int j = i; + boolean isDir = true; + while (j < n && s.charAt(j) != '\n') { + if (s.charAt(j++) == '.') isDir = false; + } + String cur = s.substring(i, j); + String prev = map.getOrDefault(level - 1, null); + String path = prev == null ? cur : prev + "/" + cur; + if (isDir) map.put(level, path); + else if (ans == null || path.length() > ans.length()) ans = path; + i = j + 1; + } + return ans == null ? 0 : ans.length(); + } +} +``` +* 时间复杂度:$O(n)$ +* 空间复杂度:$O(n)$ + +--- + +### 优化 + +上述做法只是为了方便我们输出具体方案。 + +实际上,我们只关心最终的路径长度,而不关心具体路径,因此容易将解法一修改为只记录长度,而不记录路径的做法,从而避免掉字符串拼接带来的消耗,同时利用 `s` 的长度数据范围,使用数组来替代常数较大的哈希表。 + +代码: +```Java +class Solution { + static int[] hash = new int[10010]; + public int lengthLongestPath(String s) { + Arrays.fill(hash, -1); + int n = s.length(), ans = 0; + for (int i = 0; i < n; ) { + int level = 0; + while (i < n && s.charAt(i) == '\t' && ++level >= 0) i++; + int j = i; + boolean isDir = true; + while (j < n && s.charAt(j) != '\n') { + if (s.charAt(j++) == '.') isDir = false; + } + Integer cur = j - i; + Integer prev = level - 1 >= 0 ? hash[level - 1] : -1; + Integer path = prev + 1 + cur; + if (isDir) hash[level] = path; + else if (path > ans) ans = path; + i = j + 1; + } + return ans; + } +} +``` +* 时间复杂度:$O(n)$ +* 空间复杂度:$O(C)$ + +--- + +### 最后 + +这是我们「刷穿 LeetCode」系列文章的第 `No.388` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 + +在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 + +为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 + +在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 + diff --git "a/LeetCode/821-830/824. \345\261\261\347\276\212\346\213\211\344\270\201\346\226\207\357\274\210\347\256\200\345\215\225\357\274\211.md" "b/LeetCode/821-830/824. \345\261\261\347\276\212\346\213\211\344\270\201\346\226\207\357\274\210\347\256\200\345\215\225\357\274\211.md" new file mode 100644 index 00000000..8747de80 --- /dev/null +++ "b/LeetCode/821-830/824. \345\261\261\347\276\212\346\213\211\344\270\201\346\226\207\357\274\210\347\256\200\345\215\225\357\274\211.md" @@ -0,0 +1,85 @@ +### 题目描述 + +这是 LeetCode 上的 **[824. 山羊拉丁文]()** ,难度为 **简单**。 + +Tag : 「模拟」 + + + +给你一个由若干单词组成的句子 `sentence`,单词间由空格分隔。每个单词仅由大写和小写英文字母组成。 + +请你将句子转换为 “山羊拉丁文(`Goat Latin`)”(一种类似于 猪拉丁文 - Pig Latin 的虚构语言)。山羊拉丁文的规则如下: + +* 如果单词以元音开头(`'a'`, `'e'`, `'i'`, `'o'`, `'u'`),在单词后添加`"ma"`。 + * 例如,单词 `"apple"` 变为 `"applema"` 。 +* 如果单词以辅音字母开头(即,非元音字母),移除第一个字符并将它放到末尾,之后再添加`"ma"`。 + * 例如,单词 `"goat"` 变为 `"oatgma"` 。 +* 根据单词在句子中的索引,在单词最后添加与索引相同数量的字母`'a'`,索引从 $1$ 开始。 + * 例如,在第一个单词后添加 `"a"`,在第二个单词后添加 `"aa"`,以此类推。 + +返回将 `sentence` 转换为山羊拉丁文后的句子。  + +示例 1: +``` +输入:sentence = "I speak Goat Latin" + +输出:"Imaa peaksmaaa oatGmaaaa atinLmaaaaa" +``` +示例 2: +``` +输入:sentence = "The quick brown fox jumped over the lazy dog" + +输出:"heTmaa uickqmaaa rownbmaaaa oxfmaaaaa umpedjmaaaaaa overmaaaaaaa hetmaaaaaaaa azylmaaaaaaaaa ogdmaaaaaaaaaa" +``` + +提示: +* $1 <= sentence.length <= 150$ +* `sentence` 由英文字母和空格组成 +* `sentence` 不含前导或尾随空格 +* `sentence` 中的所有单词由单个空格分隔 + +--- + +### 模拟 + +根据题意进行模拟即可。 + +代码: +```Java +class Solution { + public String toGoatLatin(String s) { + int n = s.length(); + String last = "a"; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < n; ) { + int j = i; + while (j < n && s.charAt(j) != ' ') j++; + if ("aeiouAEIOU".indexOf(s.charAt(i)) >= 0) { + sb.append(s.substring(i, j)).append("ma"); + } else { + sb.append(s.substring(i + 1, j)).append(s.charAt(i)).append("ma"); + } + sb.append(last); + last += "a"; + i = j + 1; + if (i < n) sb.append(" "); + } + return sb.toString(); + } +} +``` +* 时间复杂度:$O(n)$ +* 空间复杂度:$O(n)$ + +--- + +### 最后 + +这是我们「刷穿 LeetCode」系列文章的第 `No.824` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 + +在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 + +为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 + +在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 +