Simplify Path 4ms Java Solution
来源:互联网 发布:centos 软件安装 编辑:程序博客网 时间:2024/05/07 16:48
这是leetcode中一道在线编程题,原问题链接为
https://leetcode.com/problems/simplify-path/
原问题描述很简单,如下:
Given an absolute path for a file (Unix-style), simplify it.
For example,
path = “/home/”, => “/home”
path = “/a/./b/../../c/”, => “/c”
也就是简化Unix风格的文件的绝对路径,该问题难度不大,解决方案主要用栈 来解决,但是这里面存在的一些细节问题,使得快速编写出正确的solution也并不是那么轻松,接下来的任务就是整理这一过程,尽量使该问题的解决方案条理清晰。
首先对问题进行分析,Unix文件的绝对路径最简单的形式是“/#/#/…. /#”,其中#代表任意不包含‘/’(‘/’是Unix风格目录的分隔符)的字符串,且该字符串不为“.”和“..”。因为“.”代表当前目录,可省略;而“..”表上级目录,可以进一步简化,即“/#/#/..”可以简化为“/#/”,这就需要用到栈 的性质了。此外,需要注意的一点就是绝对路径最终的形式总是要以“/”为开头,否则为无效路径。
所以,我们算法可描述如下:
首先对原始的路径字符串path以“/”为分隔符,将其分为字符串数组。分割的方法可以是遍历字符串path的每个字符并以“/”为分割标志,也可以用Java中String自带的方法split()来分割。注意这两种方法存在效率差异,后面会有说明。
然后,按顺序从左到右对字符串数组进行栈操作,可能的字符串有{“”, “.”, “..”, 其他形式}, 其中
- 若字符串为“”或“.”,不做任何处理;
- 若字符串为“..”,则执行出栈 操作(注意,若栈为空,不做任何操作);
- 否则, 执行压栈 操作。
最后,就是还原最终的路径了,将栈底至栈顶的字符串从左到右填进“/#/#/…. /#”格式中的“#”中去。
算法时间的复杂度为遍历字符串path中字符的时间,为O(n),n为path的长度。空间复杂度亦是O(n),因为最终需要返回至多为n长度的简单路径。
下面贴一下我的Java代码:
public class Solution { public String simplifyPath(String path) { int len = path.length(); String[] stack = new String[len]; int pop = -1; int index = 0; while (index < len) { if (path.charAt(index) == '/') { continue; } int tail = index; while (tail < len && path.charAt(tail) != '/') tail++; String sub = path.substring(index, tail); if (sub.equals("..")){ if (pop >= 0) --pop; } else if (!sub.equals(".")) { stack[++pop] = sub; } index = tail + 1; } if(pop == -1) return "/"; StringBuilder simplifiedPath = new StringBuilder(); for (int i = 0; i <= pop; i++) { simplifiedPath.append("/"); simplifiedPath.append(stack[i]); } return simplifiedPath.toString(); }}
上述代码没有用String自带的方法split()来分割字符串,而是通过直接遍历字符串中字符实现,在leetcode官网其完成252个测试用例用时4ms。
下边与用split()方法分割字符串对比一下性能。其代码实现如下:
public class Solution { public String simplifyPath(String path) { int len = path.length(); String[] stack = new String[len]; int pop = -1; String[] subs = path.split("/"); for (int i = 0; i < subs.length; i++) { if (subs[i].equals("") || subs[i].equals(".")) continue; if (subs[i].equals("..")) { if (pop >= 0) --pop; }else stack[++pop] = subs[i]; } if(pop == -1) return "/"; StringBuilder simplifiedPath = new StringBuilder(); for (int i = 0; i <= pop; i++) { simplifiedPath.append("/"); simplifiedPath.append(stack[i]); } return simplifiedPath.toString(); }}
在leetcode官网其完成252个测试用例用时8ms,速度要慢上一倍。因此,从性能优化的角度来考虑,除非必要,应该尽量避免使用split,split由于支持正则表达式,所以效率会比较低,调用频率太高将会耗费大量资源。
- Simplify Path 4ms Java Solution
- [Leetcode] Simplify Path (Java)
- Simplify Path (Java)
- [LeetCode][Java] Simplify Path
- LeetCode|Simplify Path-java
- Simplify Path leetcode java
- LeetCode71 Simplify Path java题解
- (Java)LeetCode-71. Simplify Path
- 【leetcode】71. Simplify Path【java】
- [LeetCode] 71. Simplify Path java
- [leetcode]71. Simplify Path@Java
- Simplify Path
- Simplify Path
- Simplify Path
- Simplify Path
- Simplify Path
- Simplify Path
- Simplify Path
- Android完美检测键盘弹出/收起
- 第一本十一章上机3
- maven scope含义的说明
- 自定义控件三部曲之动画篇(五)——ValueAnimator高级进阶(一)
- NYOJ801-哈夫曼编码(贪心AC)
- Simplify Path 4ms Java Solution
- android多国语言文件夹
- git webhook 代码自动部署
- linux 内存管理 - 分配页面
- AngularJs $scope作用域 深入探究
- Web开发中文乱码问题
- 【洛谷2439】【SDOI2005】阶梯教室设备利用
- .net 技术交流QQ群
- Python入门——函数