【LeetCode】71. Simplify Path

题目:

Given an absolute path for a file (Unix-style), simplify it. Or in other words, convert it to the canonical path.

In a UNIX-style file system, a period . refers to the current directory. Furthermore, a double period .. moves the directory up a level. For more information, see: Absolute path vs relative path in Linux/Unix

Note that the returned canonical path must always begin with a slash /, and there must be only a single slash / between two directory names. The last directory name (if it exists) must not end with a trailing /. Also, the canonical path must be the shortest string representing the absolute path.

 

Example 1:

Input: "/home/"
Output: "/home"
Explanation: Note that there is no trailing slash after the last directory name.

Example 2:

Input: "/../"
Output: "/"
Explanation: Going one level up from the root directory is a no-op, as the root level is the highest level you can go.

Example 3:

Input: "/home//foo/"
Output: "/home/foo"
Explanation: In the canonical path, multiple consecutive slashes are replaced by a single one.

Example 4:

Input: "/a/./b/../../c/"
Output: "/c"

Example 5:

Input: "/a/../../b/../c//.//"
Output: "/c"

Example 6:

Input: "/a//b////c/d//././/.."
Output: "/a/b/c"

 

描述:

给出一个字符串表示unix系统下的路径,尝试输出该路径简化后的结果,要求,

路径必须以 / 开始,不能以 / 结尾,相邻两级目录之间只能有一个 / ,

 . 表示当前目录,..表示上级目录,/ 为根目录,其上级目录是 / 

 

分析:

用current标记已简化部分的末尾位置,随后遍历该路径,

分情况讨论,

1,遇到 / 时,若current处不为 / ,则放入 / ,否则不操作

2, 若遇到单个 "."(".." 或 ".a" 这种不算单个 "."),则跳过,不处理

3, 若遇到 ".." ( “..a” 或 "..." 不算),分情况讨论:

        1), 若current所在不为根目录,则current回退到上一个 / 的位置处重新开始

        2), 否则跳过这两个点

4, 对于其他情况,认为是路径名,添加到有效的path中

 

最后注意去掉可能存在的多余的  "/"

 

样例:

"/..."
"/.a"
"/home/"
"/../"
"/home//foo/"
"/a/./b/../../c/"
"/a/../../b/../c//.//"
"/a//b////c/d//././/.."

 

代码:(时间复杂度 O (n),空间复杂度O (1),因为只使用了path本身的空间)

class Solution {
public:
    string simplifyPath(string path) {
		int current = 0;
		for (int i = 1; i < path.size(); ++ i) {
			if (path[i] == '/') {
				if (path[current] != '/') {
					path[++ current] = '/';
				}
			} else if (onePoint(path, i)) {//只有一个点
				++ i;
			} else if (twoPoint(path, i)) {//有连续两个点
				if (current) {//若非根目录
					-- current;
					while (path[current] != '/') {
						-- current;
					}
				} else {
					++ i;//跳过这两个点
				}
			} else {//对于其他情况,认为是路径名
				while (i < path.size() && path[i] != '/') {
					path[++ current] = path[i];
					++ i;
				}
				-- i;
			}
		}
		if (!current || path[current] != '/') {
			++ current;
		}
		return path.substr(0, current);
	}
	bool onePoint(const string &s, int index) {
		if (s[index] != '.') {//当前位置不为点
			return false;
		}
		if (index + 1 >= s.size()) {//已到顶部
			return true;
		}
		return s[index + 1] == '/';
	}
	
	bool twoPoint(const string &s, int index) {
		if (s[index] != '.' || index + 1 >= s.size() || s[index + 1] != '.') {//当前位置不为点
			return false;
		}
		++ index;
		
		if (index + 1 >= s.size()) {//已到顶部
			return true;
		}
		return s[index + 1] == '/';
	}
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值