题目描述

C78B0836-0B4F-4903-88A4-C2EB02D373DB_1_201_a.jpeg

题目链接

https://leetcode.cn/problems/simplify-path/

思路

我们首先将给定的字符串【71】简化路径 - 图2根据「【71】简化路径 - 图3」分割成一个由若干字符串组成的列表,记为【71】简化路径 - 图4。根据题目中规定的「规范路径的下述格式」,【71】简化路径 - 图5中包含的字符串只能为以下几种:

  • 空字符串。例如当出现多个连续的「【71】简化路径 - 图6」,就会分割出空字符串;
  • 一个点「【71】简化路径 - 图7」;
  • 两个点「【71】简化路径 - 图8」;
  • 只包含英文字母、数字或「【71】简化路径 - 图9」的目录名。

对于「空字符串」以及「【71】简化路径 - 图10」,我们实际上无需对它们进行处理,因为「空字符串」没有任何含义,而「【71】简化路径 - 图11」表示当前目录本身,我们无需切换目录。对于「【71】简化路径 - 图12」或者「目录名」,我们则可以用一个栈来维护路径中的每一个目录名。当我们遇到「【71】简化路径 - 图13」时,需要将目录切换到上一级,因此只要栈不为空,我们就弹出栈顶的目录。当我们遇到「目录名」时,就把它放入栈。

这样一来,我们只需要遍历【71】简化路径 - 图14中的每个字符串并进行上述操作即可。在所有的操作完成后,我们将从栈底到栈顶的字符串用「【71】简化路径 - 图15」进行连接,再在最前面加上「【71】简化路径 - 图16」表示根目录,就可以得到简化后的规范路径。

代码实现

  1. public String simplifyPath(String path) {
  2. Deque<String> stack = new ArrayDeque<>();
  3. // 按下划线切分,即便是多个///也会被分割为空字符串
  4. String[] names = path.split("/");
  5. for (String name : names) {
  6. if (".".equals(name) || "".equals(name)) {
  7. continue;
  8. }
  9. // 返回上一级
  10. if ("..".equals(name)) {
  11. if (!stack.isEmpty()) {
  12. stack.pop();
  13. }
  14. } else {
  15. // 将目录名入栈
  16. stack.push(name);
  17. }
  18. }
  19. // 拼接路径
  20. StringBuilder ans = new StringBuilder();
  21. if (!stack.isEmpty()) {
  22. while (!stack.isEmpty()) {
  23. ans.append("/");
  24. ans.append(stack.pollLast());
  25. }
  26. } else {
  27. ans.append("/");
  28. }
  29. return ans.toString();
  30. }

复杂度分析

  • 时间复杂度:【71】简化路径 - 图17,其中【71】简化路径 - 图18是字符串【71】简化路径 - 图19的长度。
  • 空间复杂度:【71】简化路径 - 图20。我们需要【71】简化路径 - 图21的空间存储【71】简化路径 - 图22中的所有字符串。