Skip to content

Commit 0d95b63

Browse files
committed
Add solution of SimplifyPath task
1 parent bb7f9b2 commit 0d95b63

File tree

2 files changed

+119
-0
lines changed

2 files changed

+119
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package by.andd3dfx.collections;
2+
3+
import java.util.ArrayDeque;
4+
import java.util.Arrays;
5+
import java.util.Deque;
6+
import java.util.List;
7+
8+
/**
9+
* <pre>
10+
* <a href="https://leetcode.com/problems/simplify-path/description/">Task description</a>
11+
*
12+
* You are given an absolute path for a Unix-style file system, which always begins with a slash '/'. Your task is to transform this absolute path into its simplified canonical path.
13+
*
14+
* The rules of a Unix-style file system are as follows:
15+
*
16+
* A single period '.' represents the current directory.
17+
* A double period '..' represents the previous/parent directory.
18+
* Multiple consecutive slashes such as '//' and '///' are treated as a single slash '/'.
19+
* Any sequence of periods that does not match the rules above should be treated as a valid directory or file name. For example, '...' and '....' are valid directory or file names.
20+
*
21+
* The simplified canonical path should follow these rules:
22+
*
23+
* The path must start with a single slash '/'.
24+
* Directories within the path must be separated by exactly one slash '/'.
25+
* The path must not end with a slash '/', unless it is the root directory.
26+
* The path must not have any single or double periods ('.' and '..') used to denote current or parent directories.
27+
*
28+
* Return the simplified canonical path.
29+
*
30+
* Example 1:
31+
* Input: path = "/home/"
32+
* Output: "/home"
33+
* Explanation:
34+
* The trailing slash should be removed.
35+
*
36+
* Example 2:
37+
* Input: path = "/home//foo/"
38+
* Output: "/home/foo"
39+
* Explanation:
40+
* Multiple consecutive slashes are replaced by a single one.
41+
*
42+
* Example 3:
43+
* Input: path = "/home/user/Documents/../Pictures"
44+
* Output: "/home/user/Pictures"
45+
* Explanation:
46+
* A double period ".." refers to the directory up a level (the parent directory).
47+
*
48+
* Example 4:
49+
* Input: path = "/../"
50+
* Output: "/"
51+
* Explanation:
52+
* Going one level up from the root directory is not possible.
53+
*
54+
* Example 5:
55+
* Input: path = "/.../a/../b/c/../d/./"
56+
* Output: "/.../b/d"
57+
* Explanation:
58+
* "..." is a valid name for a directory in this problem.
59+
* </pre>
60+
*/
61+
public class SimplifyPath {
62+
63+
public static String simplifyPath(String path) {
64+
Deque<String> stack = new ArrayDeque<>();
65+
66+
path = path.replaceAll("/+", "/");
67+
StringBuilder accumulator = new StringBuilder();
68+
var chars = path.toCharArray();
69+
var i = 1;
70+
while (i < chars.length) {
71+
switch (chars[i]) {
72+
case '/':
73+
if (accumulator.toString().equals("..") && !stack.isEmpty()) {
74+
stack.pop();
75+
} else {
76+
checkAndPush(stack, accumulator);
77+
}
78+
accumulator = new StringBuilder();
79+
break;
80+
81+
default:
82+
accumulator.append(chars[i]);
83+
}
84+
i++;
85+
}
86+
checkAndPush(stack, accumulator);
87+
88+
List<String> folders = Arrays.stream(stack.toArray(new String[0]))
89+
.toList()
90+
.reversed();
91+
return "/" + String.join("/", folders);
92+
}
93+
94+
private static void checkAndPush(Deque<String> stack, StringBuilder accumulator) {
95+
var string = accumulator.toString();
96+
if (!string.isEmpty() && !string.matches("\\.{1,2}")) {
97+
stack.push(string);
98+
}
99+
}
100+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package by.andd3dfx.collections;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import org.junit.Test;
6+
7+
public class SimplifyPathTest {
8+
9+
@Test
10+
public void testSimplifyPath() {
11+
assertThat(SimplifyPath.simplifyPath("/home/")).isEqualTo("/home");
12+
assertThat(SimplifyPath.simplifyPath("/home//foo/")).isEqualTo("/home/foo");
13+
assertThat(SimplifyPath.simplifyPath("/home/user/Documents/../Pictures"))
14+
.isEqualTo("/home/user/Pictures");
15+
assertThat(SimplifyPath.simplifyPath("/../")).isEqualTo("/");
16+
assertThat(SimplifyPath.simplifyPath("/.../a/../b/c/../d/./"))
17+
.isEqualTo("/.../b/d");
18+
}
19+
}

0 commit comments

Comments
 (0)