?LeetCode刷題實(shí)戰(zhàn)71:簡化路徑
算法的重要性,我就不多說了吧,想去大廠,就必須要經(jīng)過基礎(chǔ)知識和業(yè)務(wù)邏輯面試+算法面試。所以,為了提高大家的算法能力,這個(gè)公眾號后續(xù)每天帶大家做一道算法題,題目就從LeetCode上面選 !
今天和大家聊的問題叫做?簡化路徑,我們先來看題面:
https://leetcode-cn.com/problems/simplify-path/
Given an absolute path for a file (Unix-style), simplify it. Or in other words, convert it to the canonical path.
In a UNIX-style file system, a period . refers to the current directory. Furthermore, a double period .. moves the directory up a level.
Note that the returned canonical path must always begin with a slash /, and there must be only a single slash / between two directory names. The last directory name (if it exists) must not end with a trailing /. Also, the canonical path must be the shortest string representing the absolute path.
題意
示例 1:
輸入:"/home/"
輸出:"/home"
解釋:注意,最后一個(gè)目錄名后面沒有斜杠。
示例 2:
輸入:"/../"
輸出:"/"
解釋:從根目錄向上一級是不可行的,因?yàn)楦悄憧梢缘竭_(dá)的最高級。
示例 3:
輸入:"/home//foo/"
輸出:"/home/foo"
解釋:在規(guī)范路徑中,多個(gè)連續(xù)斜杠需要用一個(gè)斜杠替換。
示例 4:
輸入:"/a/./b/../../c/"
輸出:"/c"
示例 5:
輸入:"/a/../../b/../c//.//"
輸出:"/c"
示例 6:
輸入:"/a//b////c/d//././/.."
輸出:"/a/b/c"
解題
4.1 如果是連續(xù)的"/", i++ , j=i;
4.2 如果指針j指向非"/", 持續(xù)右移j
4.3 j將停留的位置要么是path遍歷結(jié)束, 要么是"/"
4.3.1 如果j將path遍歷結(jié)束, 可以直接substring(i,j)
4.3.2 如果j停留在"/"處, 也可以直接substring(i,j)
4.4 比較substring(i,j) == "..", 棧彈出,相當(dāng)于回到上一層目錄
4.5 比較substring(i,j) == ".", 讓i指向j指向的"/", 否則, 表示substring(i,j)是一個(gè)合法目錄,將其壓棧
5.1 所有路徑以"/"開始, 因此i,j指針下標(biāo)從1開始
5.2 遇到".."時(shí), 需要保證棧不為空
5.3 遇到非".", ".."時(shí), 才需要壓棧
5.4 所有情況都需要將i更新為j, 讓i始終指向分界字符 "/"
class?Solution?{
????public?String simplifyPath(String path) {
????????if(path == null?|| path.length() < 1) return?path;
????????Stackstk = new?Stack();
????????// 主要是邊界問題
????????for(int?i = 1, j = 1; i < path.length(); i++, j = i){
????????????if(path.charAt(i-1) == '/'?&& path.charAt(i) == '/') { continue;}
????????????while(j < path.length() && path.charAt(j) != '/') j++;
????????????String tmp = path.substring(i, j);
????????????if("..".equals(tmp) && stk.size() > 0){
????????????????stk.pop();
????????????}else?if(!".".equals(tmp) && !"..".equals(tmp)){
????????????????stk.push(tmp);
????????????}
????????????i = j;
????????}
????????if(stk.size() == 0) return?"/";
????????StringBuilder sb = new?StringBuilder();
????????while(stk.size() > 0){
????????????sb.insert(0, "/"+stk.pop());
????????}
????????return?sb.toString();
????}
}
上期推文:
