Topic:
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/"
.
Should ignore redundant slashes and return "/home/foo"
.
idea: This is one of the more common operations in the Linux kernel, which is to simplify an input file path. Let's take a look at what these symbols mean in UNIX paths:
- "/." Represents this level of directory, which can be ignored
- "/.." Indicates the return to the previous level of the directory, even if the first level of the directory exists, together with "/..." Delete, or delete only the "/..."
- If the path is empty after redundancy is removed, return "/"
- If more than one consecutive "/" is included, remove the extra "/"
After knowing what we are going to do, we want to maintain a stack for each block (with a "/" as a delimiter) to analyze if you encounter ". /"means to go back to the previous layer, then the stack operation (if the stack is not empty), if you encounter"./"in the current layer, then skip directly, do not operate, the other file path directly into the stack, placed at the tail of the stack. Finally, based on the contents of the stack into a path, note that we use the list of doubly linked list features, and Java linkedlist Similar, list also contains the stack and the implementation of the queue. This way, when we restore the path, we do not need to maintain a stack to solve the problem of the order of the path, directly from the stack head out of the stack.
Attention:
1. C + + list doubly linked list.
Get the element function: Front (); back ();
Access Stack/queue function: Push_back (); Pop_back (); Push_front (); Pop_front () ;
We can choose the right function to operate according to our own needs.
2. String Compare function
int compare (const string& str) const;
If equal, returns 0;
if (Tmp.compare (".") = = 0)
3. If the path is empty after removing redundancy, return "/"
if (ret.size () = = 0) return "/";
4. Note how to get the elements between the delimiters "/" and do the operation, we traverse through the path.
while (I < path.size ()) { int index = i; Intercepts string tmp between '/' strings ; while (I < path.size () && path[i] = '/') { tmp + = path[i]; i++; }
5. First get the element of the queue header, then Pop_front (), convert to normal path.
while (!stk.empty ()) { ret + = "/" + Stk.front (); Stk.pop_front (); }
complexity: O (n) space is also O (n), stack size
AC Code:
Class Solution {public:string Simplifypath (string path) {if (path.size () = = 0) return ""; List<string> Stk; string ret; int i = 0; while (I < path.size ()) {int index = i; Intercepts string tmp between '/' strings; while (I < path.size () && path[i] = '/') {tmp + = Path[i]; i++; if (Index! = i) {if (Tmp.compare (".") = = 0) { Continue } else if (Tmp.compare ("..") = = 0) {if (!stk.empty ()) { Stk.pop_back (); }} else {stk.push_back (TMP); }} i++; } while (!stk.empty ()) {ret + = "/" + STK.Front (); Stk.pop_front (); } if (ret.size () = = 0) return "/"; return ret; }};
This problem, we can also use an array to store the elements between delimiters, so that we can directly through the subscript to manipulate the elements. Arrays also have push_back and Pop_back functions. You can look at this blog post: Simplify Path
However, through this problem, we understand that the C + + list data structure is powerful and easy to use. Make good use of it later.
[C + +] leetcode:117 Simplify path (simplified UNIX path list doubly linked list)