详细见:leetcode.com/problems/simplify-path
Java Solution: github
package leetcode;
/*
* Given an absolute path for a file (Unix-style), simplify it.
For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
click to show corner cases.
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".
*/
public class P071_SimplifyPath {
/*
* 建立最简单的树形结构
* 6 ms
*/
static class Solution1 {
public String simplifyPath(String path) {
int len = 0;
if (path == null || (len = path.length()) < 2)
return path;
Node head = new Node(), cur = head;
StringBuilder st = new StringBuilder();
boolean isLastSlash = true;
boolean isLastDot = false;
boolean isDoubleDot = false;
boolean isDoubleDotLast = false;
for (int i = 0; i <= len; i ++) {
char c = '\0';
if (i == len || (c = path.charAt(i)) == '/') {
if (isLastSlash || (isLastDot && ! isDoubleDot)) {
if (st.length() != 0)
st = new StringBuilder();
isLastSlash = true;
isDoubleDot = false;
continue;
}
if (isDoubleDot) {
if (st.length() == 2) {
if (i != len) {
cur = cur.pre == null ? cur : cur.pre;
isDoubleDotLast = true;
} else {
if (cur.pre != null)
cur.pre.next = null;
}
} else {
if (! st.toString().equals(".")) {
Node temp = new Node();
temp.str = st.toString();
temp.pre = cur;
cur.next = temp;
cur = temp;
}
}
st = new StringBuilder();
isDoubleDot = false;
continue;
}
if (! st.toString().equals(".")) {
Node temp = new Node();
temp.str = st.toString();
temp.pre = cur;
cur.next = temp;
cur = temp;
}
st = new StringBuilder();
isDoubleDot = false;
isLastDot = false;
isLastSlash = true;
} else if (c == '.') {
if (isLastDot)
isDoubleDot = true;
st.append(".");
isLastDot = true;
isLastSlash = false;
isDoubleDotLast = false;
} else {
st.append(c);
isDoubleDot = false;
isLastDot = false;
isLastSlash = false;
isDoubleDotLast = false;
}
}
if (isDoubleDotLast && cur != null)
cur.next = null;
if (cur.str == null)
cur.next = null;
if (cur.next != null)
cur.next = null;
Node travel = head;
StringBuilder ans = new StringBuilder();
while (travel != null) {
ans.append(travel.str == null ? "/" : travel.str);
if (travel != head && travel.next != null)
ans.append("/");
travel = travel.next;
}
return ans.toString();
}
static class Node {
String str = null;
Node pre;
Node next;
public Node() {}
public Node(String str, Node pre, Node next) {
this.str = str;
this.pre = pre;
this.next = next;
}
}
}
}
C Solution: github
/*
url: leetcode.com/problems/simplify-path
AC 6ms 28.00%
*/
#include <stdio.h>
#include <stdlib.h>
//element type
typedef int T;
typedef struct dll sdll;
typedef struct dll * pdll;
typedef struct dln sdln;
typedef struct dln * pdln;
//doubly list node
struct dln {
T val;
pdln pre;
pdln nxt;
};
//doubly linked list
struct dll {
pdln first;
pdln last;
int size;
};
pdll dll_init() {
pdll l = (pdll) malloc(sizeof(sdll));
l->first = NULL;
l->last = NULL;
l->size = 0;
return l;
}
void dll_add_first(pdll l, T v) {
pdln t = (pdln) malloc(sizeof(sdln));
t->val = v;
t->pre = NULL;
t->nxt = NULL;
if (l->size == 0) {
l->first = t;
l->last = t;
l->size = 1;
return;
}
t->nxt = l->first;
l->first->pre = t;
l->first = t;
l->size ++;
}
void dll_add_last(pdll l, T v) {
pdln t = (pdln) malloc(sizeof(sdln));
t->val = v;
t->pre = NULL;
t->nxt = NULL;
if (l->size == 0) {
l->first = t;
l->last = t;
l->size = 1;
return;
}
t->pre = l->last;
l->last->nxt = t;
l->last = t;
l->size ++;
}
void dll_remove_first(pdll l) {
pdln t = NULL;
if (l->first == NULL) return;
if (l->first == l->last) {
free(l->first);
l->first = NULL;
l->last = NULL;
l->size = 0;
return;
}
t = l->first->nxt;
t->pre = NULL;
free(l->first);
l->first = t;
l->size --;
}
void dll_remove_last(pdll l) {
pdln t = NULL;
if (l->last == NULL) return;
if (l->first == l->last) {
free(l->first);
l->first = NULL;
l->last = NULL;
l->size = 0;
return;
}
t = l->last->pre;
t->nxt = NULL;
free(l->last);
l->last = t;
l->size --;
}
T* dll_convert_to_array(pdll l) {
T* arr = NULL;
int arr_index = 0;
pdln travel = NULL;
pdln t1 = NULL, t2 = NULL;
if (l == NULL || l->size == 0) return arr;
arr = (T*) malloc(sizeof(T) * l->size);
travel = l->first;
while (travel != NULL) {
arr[arr_index ++] = travel->val;
travel = travel->nxt;
}
t1 = l->first;
while (t1 != NULL) {
t2 = t1->nxt;
free(t1);
t1 = t2;
}
free(l);
return arr;
}
void dll_print(pdll l) {
pdln t = l == NULL ? NULL : l->first;
while (t != NULL) {
printf("%d ", t->val);
t = t->nxt;
}
printf("\r\n");
}
void dll_free_all(pdll l) {
pdln t1 = l->first, t2 = NULL;
while (t1 != NULL) {
t2 = t1->nxt;
free(t1);
t1 = t2;
}
free(l);
}
char* simplifyPath(char* p) {
pdll l = dll_init();
int pn = 0, i = 0, sti = 0, len = 0, ai = 0;
char c = '\0', *ans = NULL;
pdln n = NULL;
while (1) {
c = p[i ++];
if (c == '\0') break;
if (c == '/') {
if (len == 2 && p[sti] == '.' && p[sti+1] == '.') {
dll_remove_last(l);
} else if (len != 0 && ! (len == 1 && p[sti] == '.')) {
dll_add_last(l, sti);
}
sti = i;
len = 0;
continue;
}
len ++;
}
if (len == 2 && p[sti] == '.' && p[sti+1] == '.') {
dll_remove_last(l);
} else if (len != 0 && ! (len == 1 && p[sti] == '.')) {
dll_add_last(l, sti);
}
pn = i;
ans = (char*) malloc(sizeof(char) * pn);
n = l->first;
while (n != NULL) {
i = n->val;
ans[ai ++] = '/';
while (1) {
c = p[i++];
if (c == '\0' || c == '/') break;
ans[ai ++] = c;
}
n = n->nxt;
}
ans[ai ++] = '\0';
if (l->first == NULL) {
ans[0] = '/';
ans[1] = '\0';
return ans;
}
return ans;
}
int main() {
char* p = "/home//foo/";
char* a = simplifyPath(p);
printf("answer is %s\r\n", a);
free(a);
return 0;
}
Python Solution: github
#coding=utf-8
'''
url: leetcode.com/problems/simplify-path/
@author: zxwtry
@email: zxwtry@qq.com
@date: 2017年4月16日
@details: Solution: 65ms 36.88%
'''
class Solution(object):
def simplifyPath(self, p):
"""
:type p: str
:rtype: str
"""
ps = p.split("/")
l = []
for s in ps:
if s == "": continue
if s == ".": continue
if s == "..":
if len(l) > 0: l.pop()
continue
l.append(s)
if len(l) == 0:
return "/"
ans = ""
for s in l:
ans += "/"
ans += s
return ans
if __name__ == "__main__":
p = "/"
print(Solution().simplifyPath(p))