zoukankan      html  css  js  c++  java
  • 71. 简化路径

    欢迎关注我的公众号《小沈干货》,谢谢大家。

    以 Unix 风格给出一个文件的绝对路径,你需要简化它。或者换句话说,将其转换为规范路径。

    在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。更多信息请参阅:Linux / Unix中的绝对路径 vs 相对路径

    请注意,返回的规范路径必须始终以斜杠 / 开头,并且两个目录名之间必须只有一个斜杠 /。最后一个目录名(如果存在)不能/ 结尾。此外,规范路径必须是表示绝对路径的最短字符串。

    示例 1:

    输入:"/home/"
    输出:"/home"
    解释:注意,最后一个目录名后面没有斜杠。
    

    示例 2:

    输入:"/../"
    输出:"/"
    解释:从根目录向上一级是不可行的,因为根是你可以到达的最高级。
    

    示例 3:

    输入:"/home//foo/"
    输出:"/home/foo"
    解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。
    

    示例 4:

    输入:"/a/./b/../../c/"
    输出:"/c"
    

    示例 5:

    输入:"/a/../../b/../c//.//"
    输出:"/c"
    

    示例 6:

    输入:"/a//b////c/d//././/.."
    输出:"/a/b/c"


    java的解决判法如下,我没有参考网上别人的答案,我的答案AC,并且时间复杂度超过79.09%,空间复杂度超过64.76%。
    
    
    import java.util.Stack;
    
    class Solution {
        public String simplifyPath(String path) {
            Stack<Character> stack = new Stack<>();
            int flag = 0;
            int flag2 = 0;
            for (int i = 0; i < path.length(); i++) {
                char c = path.charAt(i);
                //当路径中出现不是"."和"/"字符时,应该入栈
                if (c != '.' && c != '/') {
                    //当"."的个数为偶数,"/"大于0时,表示这个时候目录要cd到上一层
                    if (flag % 2 == 0 && flag2 >= 1) {
                        //一共要向上的层数为flag/2
                        for (int j = 0; j < flag / 2; j++) {
                            if (stack.size() > 0) {
                                //出栈的第一个字符一定不会是/,这是由我们入栈的操作保证的
                                char d = stack.pop();
                                while (d != '/' && stack.size() > 0)
                                    d = stack.pop(); //直到我们出栈的字符为/时,暂停出栈
                            }
                        }
                    } else if (flag >= 1 && flag2 == 0) { //当"."的个数为基础,且"/"为0时,说明此时的几个"."字符是与字母连在一起的,需要入栈
                        stack.push('/');
                        for (int j = 0; j < flag; j++) {
                            stack.push('.');
                        }
                    }
                    //上面解决了"."字符带来的出栈和入栈,现在要入栈我们此时取到的字符
                    if (flag2 >= 1)
                        stack.push('/'); //如果"/"大于零,说明该生成下一级目录
                    stack.push(c);
                    flag = 0;
                    flag2 = 0;
                //"."个数增加,同时将之前可能取到的"/"个数清零,因为多余/是没用的
                } else if (c == '.') {
                    flag++;
                    flag2 = 0;
                //"/"个数增加,同时判断此时"."个数,为1则表示在同一层,不起作用直接清0,为2表示需要向上一级
                } else if (c == '/') {
                    flag2++;
                    if (flag == 2) {
                        for (int j = 0; j < flag / 2; j++) {
                            if (stack.size() > 0) {
                                char d = stack.pop();
                                while (d != '/' && stack.size() > 0)
                                    d = stack.pop();
                            }
                        }
                        flag = 0;
                    } else if (flag == 1)
                        flag = 0;
                }
            }
    
            //for循环结束,可能最后取出了几个"."字符,这个时候需要判断是不是要向上一级目录
            if (flag % 2 == 0) {
                for (int j = 0; j < flag / 2; j++) {
                    if (stack.size() > 0) {
                        char d = stack.pop();
                        while (d != '/' && stack.size() > 0)
                            d = stack.pop();
                    }
                }
            } else if (flag > 1) { //如果"."字符个数大于1,且为奇数,则不是正确的指令,必须入栈该奇数个"."
                stack.push('/');
                for (int j = 0; j < flag; j++) {
                    stack.push('.');
                }
            }
            //如果栈是空的
            if (stack.size() == 0)
                return "/";
            int f = 0;
            String[] arr = new String[stack.size()];
            while (stack.size() != 0) {
                arr[f] = String.valueOf(stack.pop());
                f++;
            }
            StringBuilder res = new StringBuilder();
            for (int i = arr.length - 1; i >= 0; i--) {
                res.append(arr[i]);
            }
            return res.toString();
        }
    
        public static void main(String[] args) {
    //        String path = "/a//b////c/d//././/..";
            String path = "/home/foo/.ssh/authorized_keys/";
            Solution3 solution3 = new Solution3();
            String s = solution3.simplifyPath(path);
            System.out.println(s);
        }
    }
  • 相关阅读:
    zookeeper高可用集群搭建
    linux安装配置zookeeper-3.4.10
    hadoop小结
    YARN集群的mapreduce测试(六)
    YARN集群的mapreduce测试(五)
    YARN集群的mapreduce测试(四)
    mxnet卷积神经网络训练MNIST数据集测试
    人脸识别的损失函数
    完全图解RNN、RNN变体、Seq2Seq、Attention机制
    机器学习中的线性和非线性判断
  • 原文地址:https://www.cnblogs.com/wenbinshen/p/10724036.html
Copyright © 2011-2022 走看看