好消息是,这题我刷过。
坏消息是,太久了我完全忘了。
1、看题先
点开今天的每日一题,发现已经完成时,我是一脸蒙蔽的。
愣了会才想起来,编号较小,可能之前我就已经刷到过了。
2、审题
题目罗里吧嗦,但提炼出来,就是一个栈的问题。
而对于遇到的路径命令,我们只需要遵循以下操作:
- 遇到
.
无视 - 遇到
..
返回上一级 - 遇到其他名称,进入该目录
- 遇到
//
无视
3、思路
简单扫了下题目后,曾经的思路就慢慢在脑海里浮现
很显然,我们只需要用到栈的思想,将所有需要进入的目录入栈,在遇到 ..
后将栈顶的目录出栈,以表示返回。
其他情况不做任何考虑,然后留在栈内的数据即为最终的路径。
4、动手
class Solution {
private static String DOT = ".";
private static String DOUBLE_DOT = "..";
public String simplifyPath(String path) {
String[] splits = path.split("/");
Stack<String> stack = new Stack<>();
for (String s : splits) {
//单点不做任何处理
if (s.equals("") || s.equals(DOT)) {
continue;
}
if (s.equals(DOUBLE_DOT)) {
//遇上双点时,将栈顶的元素出栈
if (!stack.isEmpty()) {
stack.pop();
}
} else {
//遇上其他时,压入栈内
stack.push(s);
}
}
//压入新栈以反转整个栈
Stack<String> otherStack = new Stack<>();
while (!stack.isEmpty()) {
otherStack.push(stack.pop());
}
//再将新栈出栈来构建地址
StringBuilder sb = new StringBuilder();
while (!otherStack.isEmpty()) {
sb.append("/");
String s = otherStack.pop();
sb.append(s);
}
//空地址时,返回/
if (sb.length() == 0) {
sb.append("/");
}
return sb.toString();
}
}
5、解读
首先,这里犯了个小蠢。在第一次的提交中,我直接将路径顺序按出栈顺序拼接,然后发现顺序倒了。
于是,要将栈内的数据反转过来,怎么办呢?大学C语言老师的教诲浮现在脑海——再拿个栈来,将前一个栈的数据依次出栈,再依次压入新栈内,最后新栈再依次出栈,顺序就翻转了。
然后就出现了这么个不伦不类的东西……
好吧,一点点来。
首先我们以/
拆分字符串,这样就可以拿到/
间的所有字符,而不用处理遇到/
和//
的情况。
之后,就如同我先前将的,.
无视,..
出栈,其他字符入栈即可。
Stack<String> stack = new Stack<>();
for (String s : splits) {
//单点不做任何处理
if (s.equals("") || s.equals(DOT)) {
continue;
}
if (s.equals(DOUBLE_DOT)) {
//遇上双点时,将栈顶的元素出栈
if (!stack.isEmpty()) {
stack.pop();
}
} else {
//遇上其他时,压入栈内
stack.push(s);
}
}
然后,就是翻转栈内的数据了……
拿个新栈接一下旧栈出栈的数据。
//压入新栈以反转整个栈
Stack<String> otherStack = new Stack<>();
while (!stack.isEmpty()) {
otherStack.push(stack.pop());
}
最后以StringBuilder
拼接字符串并返回,万事大吉。
注意如果栈为空,没有路径时,要返回/
。
6、提交
7、咀嚼
虽然遍历了多次,但不涉及到嵌套,时间复杂度为O(N)。
然后,使用了栈来存储所有字符信息,空间复杂度也为O(N)。
8、看看大牛
实际上,今天大牛们也没有什么花样,思路都是我这一样的。
不过,看了大牛的题解才发现我这那两个栈来翻转数据的做法是真的蠢。
特别是java api有提供双向队列Deque
,既能让你从尾部做出栈操作,也能让你从头部直接获取数据,十分切合此题。
高级语言的api就是你最好的算法助手!
前提当然是你得知道并且会用它们。
9、总结
这是坚持刷每日一题以来,第一次刷到之前就已经做过的题。
现在回想起之前的青涩的岁月,真是感慨万千啊……
然而最让我感慨是为什么我还是辣么的菜!
周四了,虽然你可能才上三天班,但今天确实是周四了!
努力努力,明天周五后又可以休假了。