Tuesday, April 1, 2014

Simplify Path @LeetCode

Given an absolute path for a file (Unix-style), simplify it.
For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
Corner Cases:
  • Did you consider the case where path = "/../"?
    In this case, you should return "/".
  • Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/".
    In this case, you should ignore redundant slashes and return "/home/foo".
package leetcode;
import java.util.ArrayList;
/**
* Solution: Split Path into word group. Consider "." ".." "" situation and construct absolute path.
* Similar to Reverse words in a string
*
* "." current directory doesn't matter /a/./b == /a/b
* ".." matters /a/../b == /b b is under /.
* don't forget "". We should always consider this when we use split.
*
* Test Case: "/..." don't be confused! ... could be a directory!
*
* @author jeffwan
* @date Apr 1, 2014
*/
public class SimplifyPath {
public static String simplifyPath(String path) {
String result = "/";
String[] stubs = path.split("/");
ArrayList<String> paths = new ArrayList<String>();
for (String s : stubs) {
if (s.equals("..")) {
if (paths.size() > 0) {
paths.remove(paths.size() - 1); // ".." go back parent directory. counteract last folder.
}
} else
if (!s.equals(".") && !s.equals("")) {
paths.add(s);
}
}
//It's good to handle paths.size() == 0 situation, a "/" already be included in result.
for (String s : paths) {
result += s + "/";
}
if (result.length() > 1) {
result = result.substring(0, result.length() - 1);
}
return result;
}
/*
* My solution: scan from end to front. Intercept word and stores in list.
* The result will be /word1/word2/word3. I ignore all "." because I think it's useless.
* But I failed in such test case "/..." --> except "/..."
* All in all, I didn't care the real relation between path and "." and ".."-- big mistake.
*/
public String simplifyPath2(String path) {
if (path == null || path.length() == 0) {
return "";
}
ArrayList<String> list = new ArrayList<String>();
for (int i = path.length() - 1; i >= 0; i--) {
if (path.charAt(i) == '/') {
continue;
}
if (path.charAt(i) == '.') {
break;
}
int end = i;
while (path.charAt(i) != '/') {
i--;
}
String word = path.substring(i + 1, end + 1);
list.add(0, word);
}
if (list.size() == 0) {
return "/";
}
StringBuilder sb = new StringBuilder();
for (String word : list) {
sb.append('/');
sb.append(word);
}
return sb.toString().substring(0, sb.length());
}
}

No comments:

Post a Comment