【栈】简化路径

238 阅读2分钟

题目

给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/' 开头),请你将其转化为更加简洁的规范路径。

在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//')都被视为单个斜杠 '/' 。 对于此问题,任何其他格式的点(例如,'...')均被视为文件/目录名称。

请注意,返回的 规范路径 必须遵循下述格式:

始终以斜杠 '/' 开头。 两个目录名之间必须只有一个斜杠 '/' 。 最后一个目录名(如果存在)不能 以 '/' 结尾。 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 '.' 或 '..')。 返回简化后得到的 规范路径 。

思路

看到题目首先想到的就是用栈,栈有先进后出的特点,针对..让路径后退非常符合.Java中用Stack类来操作栈。用/分割,遍历进入stack,如果为..就出栈,空或者.不用操作,其他的进栈即可。

操作方法

stack是继承Vector,Vector又继承AbstractList,实现List 除了由Vector定义的所有方法,自己也定义了一些方法:

序号方法描述
1boolean empty()  测试堆栈是否为空。
2Object peek( ) 查看堆栈顶部的对象,但不从堆栈中移除它。
3Object pop( ) 移除堆栈顶部的对象,并作为此函数的值返回该对象。
4Object push(Object element) 把项压入堆栈顶部。
5int search(Object element) 返回对象在堆栈中的位置,以 1 为基数。

代码实现

public static String simplifyPath(String path) {
    String[] split = path.split("/");
    if(split.length == 0){
        return "/";
    }
    Stack<String> stack = new Stack<>();
    for (int i = 0; i < split.length; i++) {
        if(split[i].equals(".") || split[i].equals(""))continue;
        if(split[i].equals("..")){
            if(!stack.isEmpty()){
                stack.pop();
            }
            continue;
        }
        stack.push(split[i]);
    }

    //输出路径
    StringBuilder str = new StringBuilder();
    if(stack.isEmpty()){
        str.insert(0,"/");
    }else{
        while (!stack.isEmpty()){
            str.insert(0,stack.pop());
            str.insert(0,"/");
        }
    }
    return str.toString();
}

Deque

由于Java堆栈Stack类已经过时,Java官方推荐使用Deque替代Stack使用。从继承关系来看,Deque继承Queue,Queue又继承了Collection,LinkedList实现了Deque,所以Deque具有了两端操作的能力

Deque<String> queue = new LinkedList<>();

使用

抛出异常特殊值:true|false抛出异常特殊值:true|false
插入addFirst(e)offerFirst(e)addLast(e)offerLast(e)
删除removeFirst()pollFirst()removeLast()pollLast()
检查getFirst()peekFirst()getLast()peekLast()

代码实现

String[] split = path.split("/");
if(split.length == 0){
    return "/";
}
Deque<String> queue = new LinkedList<>();
for (int i = 0; i < split.length; i++) {
    if(split[i].equals(".") || split[i].equals(""))continue;
    if(split[i].equals("..")){
        if(!queue.isEmpty()){
            queue.pollLast();
        }
        continue;
    }
    queue.offer(split[i]);
}
//输出路径
StringBuilder str = new StringBuilder("/");
while (!queue.isEmpty()){
    str.append(queue.poll());
    if(!queue.isEmpty()){
        str.append("/");
    }
}
return str.toString();




链接:https://leetcode-cn.com/problems/simplify-path

git: https://gitee.com/zhwgit/leetcode-practice.git