leetcode 简化路径 Java

题干

以 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//bc/d//././/.."
输出:"/a/b/c"

想法

从题干我们发现有的文件你虽然在相对路径里出现了但是绝对路径没有
于是肯定需要一个结构来存储,显然这个结构是需要返回离现在最近的,也就是栈的结构
先将字符串依"/"分割出来,然后检查每个分割出来的字符串。

当字符串为空或者为".",不做任何操作。

当字符串不为"…",则将字符串入栈。

当字符串为"…", 则弹栈(返回上级目录)。

最后再全部倒着出栈即可

Java代码

class Solution {
    
    /*
    *stack用来遍历的时候存每一个
    *slist存分割后的
    *res存最后的结果
    */
    public String simplifyPath(String path) {
        if(path==null||path.length()==0){
            return path;
        }
        Stack<String> stack=new Stack<>();
        
        StringBuilder sb=new StringBuilder();
        String [] slist=path.split("/");
        for(int i=0;i<slist.length;i++){
            //当前文件或者空 步操作
            if(slist[i].equals(".")||slist[i].length()==0){
                continue;
            }
            else if(slist[i].equals("..")){
                //如果要返回上一级就必然检查是否为空
                if(!stack.isEmpty()){
                    stack.pop();
                }
               
            }
             else{
                 //否则继续遍历
                    stack.push(slist[i]);
                }
        }
        if (stack.isEmpty())
            //题干说了开头都要/
            return "/";

        StringBuffer res = new StringBuffer();
        for (int i = 0; i < stack.size(); i++) {
            res.append("/" + stack.get(i));
        }
        return res.toString();
    }
}


别人的

class Solution {
    public String simplifyPath(String path) {
        String[] s = path.split("/");
        Stack<String> stack = new Stack<>();

        for (int i = 0; i < s.length; i++) {
            if (!stack.isEmpty() && s[i].equals(".."))
                stack.pop();
            else if (!s[i].equals("") && !s[i].equals(".") && !s[i].equals(".."))
                stack.push(s[i]);
        }
        if (stack.isEmpty())
            return "/";

        StringBuffer res = new StringBuffer();
        for (int i = 0; i < stack.size(); i++) {
            res.append("/" + stack.get(i));
        }
        return res.toString();
    }
}

更快的

class Solution {
    public String simplifyPath(String path) {
        int pathLen=path.length();
        char[] pathc=path.toCharArray();
        char[] simppath=new char[pathLen];
        int p=-1;//指向已有路径的末尾字符
        
        int t=0;//指向待遍历的首个字符
        while(t<pathLen) {
        	simppath[++p]='/';//刚开始t必然指向'/'
        	while(t<pathLen&&pathc[t]=='/') {
        		t++;
        	}
        	if(t<pathLen) {
        		if(pathc[t]=='.') {
        			int t1=t+1;
        			if(t1==pathLen||pathc[t1]=='/') {//本层目录
        				p--;
        				t++;
        			}else if(pathc[t1]=='.'&&(t1+1==pathLen||pathc[t1+1]=='/')) {//上层目录
        				p--;
        				while(p>-1&&simppath[p]!='/') {
        					p--;
        				}
        				p--;
        				p=p<-1?-1:p;
        				t+=2;
        			}else {
        		        while(t<pathLen&&pathc[t]!='/') {
        					simppath[++p]=pathc[t];
        					t++;
        				}
        			}
        		}else {
        	        while(t<pathLen&&pathc[t]!='/') {
        				simppath[++p]=pathc[t];
        				t++;
        			}
        		}
        	}else {
        		p--;
        	}
        }
        
        if(p==-1) simppath[++p]='/';
        
        String ans=new String(simppath,0,p+1);
        return ans;  	
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值