LeetCode.71简化路径
思路一:
遍历字符串path,记录除了"/"以外的字符,遇到"/"时停止。此时记录的字符串temp为两次"/"之间的部分,则有了四种情况:①temp = "..",②temp = ".",③temp = "",④temp = 地址值。其中2和3时什么事情也不需要做,当为4时则将"/" + temp放入StringBulider。当为1时则需要返回上一级地址,即删除从结尾到最后一个"/"处的字符, 此时又有了两种情况:①上一级地址存在,则正常删除。②目前已在根目录则不需要删除。
有如下代码。其中首先将path末尾加上"/",否则最后一个地址值记录进temp后无法进行判断,因为读不到下一个"/"。其次,当正常输入地址时需要在地址前加一个"/",因为初始的StringBuilder是空的,所以在删除时则需要在删除完地址字符后将末尾的"/"也删除。代码结尾处如果字符串长度为0则添加一个"/"表示根目录。
class Solution { public String simplifyPath(String path) { path += "/"; StringBuilder sb = new StringBuilder(); String temp = ""; for(int i = 0; i < path.length(); i++){ char c = path.charAt(i); if(c != '/') temp += c; else{ if("..".equals(temp)){ while(sb.length() > 0 && sb.charAt(sb.length() - 1) != '/') sb.deleteCharAt(sb.length() - 1); if(sb.length() > 0) sb.deleteCharAt(sb.length() - 1); //只要长度不是0就要把最后一个字符即'/'删除,因为后续还要继续加/temp,所以必须删除,然后再在结尾对结果进行判断是否为空,为空再添加"/" }else if(!".".equals(temp) && !"".equals(temp)){ sb.append("/" + temp); } temp = ""; } } return sb.length() == 0 ? "/" : sb.toString(); } }
思路二:
使用split函数对path进行按'/'切割,将切割后的字符串数组放入一个stack中,每次放入时对字符串进行判断,若为""或"."则不进行操作,若为".."则出栈,其他则入栈。对切割后的数组进行遍历后则得到一个有效的地址栈,再对栈进行遍历,则得到了最终的地址。
代码如下:
class Solution { public String simplifyPath(String path) { Stack<String> stack = new Stack<>(); for(String temp : path.split("/")){ if("..".equals(temp) && !stack.empty()) stack.pop(); if(!".".equals(temp) && !"".equals(temp) && !"..".equals(temp)) stack.push(temp); } StringBuilder sb = new StringBuilder(); for(String i : stack) sb.append("/" + i); return sb.length() == 0 ? "/" : sb.toString(); } }
方法二比方法一耗时少。
7.3日补充:
当使用Stack时正常的push和pop,入栈顺序为切割后的顺序,出栈顺序却与入栈相同,即第二个for(String i : stack)中String[] i的顺序与入栈一致。而使用Deque时,正常入栈后,若使用for(String i : stack),得到的String[] i 顺序为出栈顺序,即与用Stack时的顺序相反,所以需要用while与pollLast()函数达到与运用Stack时一样的效果。因为每次push是在栈顶添加元素,而pollLast是在栈(队)尾取元素,因此得到了如此结果。

!
浙公网安备 33010602011771号