LeetCode 386. 字典序排数 / 821. 字符的最短距离 / 388. 文件的最长绝对路径

Posted Zephyr丶J

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 386. 字典序排数 / 821. 字符的最短距离 / 388. 文件的最长绝对路径相关的知识,希望对你有一定的参考价值。

386. 字典序排数

2022.4.18 每日一题,毕业时间突然提前一个月,懵了…

题目描述

给你一个整数 n ,按字典序返回范围 [1, n] 内所有整数。

你必须设计一个时间复杂度为 O(n) 且使用 O(1) 额外空间的算法。

示例 1:

输入:n = 13
输出:[1,10,11,12,13,2,3,4,5,6,7,8,9]

示例 2:

输入:n = 2
输出:[1,2]

提示:

1 <= n <= 5 * 10^4

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/lexicographical-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

class Solution 
    public List<Integer> lexicalOrder(int n) 
        //和前几天那个题差不多,不过这个好像简单点
        //直接往后面加就可以了,如果不可以那跳回上一层
        //1 后面加 0,变成10,如果小于n,那么说明还能加,就变成100,大于n了就返回上一层,也就是当前数除以10
        //就变成了10,然后加1变成11
        List<Integer> res = new ArrayList<>();
        int idx = 1;
        res.add(idx);

        while(res.size() < n)
            //先往后边延生
            if(idx * 10 <= n)
                idx *= 10;
            //但是加1可能超过范围,例如999 + 1 = 1000 
            else
                while(idx % 10 == 9 || idx + 1 > n)
                    idx /= 10;
                
                idx++;
            
            res.add(idx);
        
        return res;
    

dfs

class Solution 
    List<Integer> res = new ArrayList<>();
    public List<Integer> lexicalOrder(int n) 
        for(int i = 1; i < 10; i++)
            dfs(i, n);
        
        return res;
    

    public void dfs(int num, int n)
        if(num > n)
            return;
        res.add(num);
        //向下一层扩展
        for(int i = 0; i < 10; i++)
            dfs(num * 10 + i, n);
        
    

821. 字符的最短距离

2022.4.19 每日一题

题目描述

给你一个字符串 s 和一个字符 c ,且 c 是 s 中出现过的字符。

返回一个整数数组 answer ,其中 answer.length == s.length 且 answer[i] 是 s 中从下标 i 到离它 最近 的字符 c 的 距离 。

两个下标 i 和 j 之间的 距离 为 abs(i - j) ,其中 abs 是绝对值函数。

示例 1:

输入:s = “loveleetcode”, c = “e”
输出:[3,2,1,0,1,0,0,1,2,2,1,0]
解释:字符 ‘e’ 出现在下标 3、5、6 和 11 处(下标从 0 开始计数)。
距下标 0 最近的 ‘e’ 出现在下标 3 ,所以距离为 abs(0 - 3) = 3 。
距下标 1 最近的 ‘e’ 出现在下标 3 ,所以距离为 abs(1 - 3) = 2 。
对于下标 4 ,出现在下标 3 和下标 5 处的 ‘e’ 都离它最近,但距离是一样的 abs(4 - 3) == abs(4 - 5) = 1 。
距下标 8 最近的 ‘e’ 出现在下标 6 ,所以距离为 abs(8 - 6) = 2 。

示例 2:

输入:s = “aaab”, c = “b”
输出:[3,2,1,0]

提示:

1 <= s.length <= 10^4
s[i] 和 c 均为小写英文字母
题目数据保证 c 在 s 中至少出现一次

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shortest-distance-to-a-character
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

我这里先记录每个c的位置,然后和每一个字符位置做比较

class Solution 
    public int[] shortestToChar(String s, char c) 
        //先统计每个字符的位置,然后对于每一个字符,找位置
        int l = s.length();
        List<Integer> list = new ArrayList<>();
        for(int i = 0; i < l; i++)
            char temp = s.charAt(i);
            if(temp == c)
                list.add(i);
        
        int[] res = new int[l];
        int idx = 1;
        int idx1 = list.get(0);
        int idx2 = list.size() > 1 ? list.get(1) : 100000;
        for(int i = 0; i < l; i++)
            if(i <= idx1)
                res[i] = idx1 - i;
            else if(i > idx1 && i < idx2)
                res[i] = Math.min(i - idx1, idx2 - i);
            else
                res[i] = 0;
                idx1 = idx2;
                idx2 = list.size() > ++idx ? list.get(idx) : 100000; 
            
        
        return res;
    

题解这种两次遍历更加简洁
注意python这个倒序输出需要反着写顺序,并且第三个参数必须得写,否则默认是正序的,即使写range(l-1, -1)也不行;另外,不取上限同样

class Solution:
    def shortestToChar(self, s: str, c: str) -> List[int]:
        l = len(s)
        res = [0] * l

        idx = -l
        for i, ch in enumerate(s):
            if ch == c:
                idx = i
            res[i] = i - idx
        
        idx = 2 * l
        for i in range(l - 1, -1, -1):
            if s[i] == c:
                idx = i
            res[i] = min(idx - i, res[i])
        return res
        

388. 文件的最长绝对路径

2022.4.20 每日一题,谷雨,春季的最后一个节气,马上立夏了

题目描述

假设有一个同时存储文件和目录的文件系统。下图展示了文件系统的一个示例:

这里将 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:


输入:input = “dir\\n\\tsubdir1\\n\\tsubdir2\\n\\t\\tfile.ext”
输出:20
解释:只有一个文件,绝对路径为 “dir/subdir2/file.ext” ,路径长度 20

示例 2:


输入: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’,一个点 ‘.’,一个空格 ’ ',和数字。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-absolute-file-path
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

最近每日一题出了很多个这种题,栈还是很容易想到的
我这个主要卡住的点就是,我以为字符串中的\\n,\\t是两个字符,结果去取\\判断,导致一直不知道哪里错了,改了以后就过了

class Solution 
    public int lengthLongestPath(String input) 
        //栈的那种结构,先放入文件夹,再放文件
        //栈中存放一个【int,int,int】的结构,表示第几级目录,当前路径长度
        //遇到字母或者数字空格,进行字符串的拼接;如果是点,那么进行特殊标记
        //遇到\\,看如果下一个是n,那么先处理当前文件,如果是文件,那么统计长度,如果是文件夹,那么放入栈中
        //然后新建一个点
        //如果下一个是t,那么给当前数据结构级别加1

        int l = input.length();
        Stack<int[]> stack = new Stack<>();
        int[] temp = new int[3];
        int max = 0;
        for(int i = 0; i < l; i++)
            char c = input.charAt(i);

            if(c == '\\n')
                //System.out.println("111");
                int level = temp[0];
                //将比当前级别高的都弹出去
                while(!stack.isEmpty() && stack.peek()[0] >= level)
                    stack.pop();
                //如果是文件夹
                if(temp[2] == 0)
                    temp[1] = stack.isEmpty() ? temp[1] + 1 : stack.peek()[1] + temp[1] + 1;
                    stack.push(temp);
                else
                    temp[1] = stack.isEmpty() ? temp[1] : stack.peek()[1] + temp[1];
                    max = Math.max(max, temp[1]);
                
                //System.out.println(temp[1]);
                temp = new int[3];
            else if(c == '\\t')
                temp[0]++;
            else
                temp[1]++;
                if(c == '.')
                    temp[2] = 1;
                if(i == l - 1 && temp[2] == 1)
                    while(!stack.isEmpty() && temp[0] <= stack.peek()[0])
                        stack.pop();
                    temp[1] = stack.isEmpty() ? temp[1] : stack.peek()[1] + temp[1];
                    max = Math.max(max, temp[1]);
                
            
        
        return max;
    

用数组模拟栈

class Solution:
    def lengthLongestPath(self, input: str) -> int:
        res = 0
        n = len(input)
        lv = [0] * n
        level = 0
        flag = False
        length = 0
        maxlen = 0
        for c in input:
            if c == '\\t':
                level += 1
            elif c == '\\n':
                if level > 0:
                   length += lv[level - 1] + 1
                if flag:
                    maxlen = max(maxlen, length)
                else:
                    lv[level] = length
                length = 0
                flag = False
                level = 0
            else:
                length += 1
                if c == '.':
                    flag = True
        if flag:
            if level > 0:
                length += lv[level - 1] + 1
            maxlen = max(maxlen, length)
        return maxlen
            

以上是关于LeetCode 386. 字典序排数 / 821. 字符的最短距离 / 388. 文件的最长绝对路径的主要内容,如果未能解决你的问题,请参考以下文章

(Java) LeetCode 386. Lexicographical Numbers —— 字典序排数

LeetCode 386 字典序排数[dfs 字典树] HERODING的LeetCode之路

386. 字典序排数

386. 字典序排数(中等)-迭代-全排列

使用DFS来解决“字典序排数”问题

使用DFS来解决“字典序排数”问题