题目链接:https://leetcode.com/problems/longest-absolute-file-path/

题目:

Suppose we abstract our file system by a string in the following manner:

"dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext"

dir subdir1 subdir2 file.ext


dir contains an empty sub-directory subdir1 and a sub-directory subdir2 containing a file file.ext."dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext"

dir subdir1 file1.ext subsubdir1 subdir2 subsubdir2 file2.ext


dir contains two sub-directories subdir1 and subdir2subdir1 contains a file file1.ext and an empty second-level sub-directory subsubdir1subdir2contains a second-level sub-directory subsubdir2 containing a file file2.ext."dir/subdir2/subsubdir2/file2.ext", and its length is 320.

Note:

  • The name of a file contains at least a 

.

  • The name of a directory or sub-directory will not contain a 

.

  • .

O(n) where na/aa/aaa/file1.txt is not the longest file path, if there is another path aaaaaaaaaaaaaaaaaaaaa/sth.png.

思路:

思路比较简单,用一个可变数组维护一个从根目录到当前目录的绝对路径的长度。。。好绕口。。= =说出来自己都不懂。。

要注意绝对路径结尾必须包含一个文件才有算有效,且绝对路径需要一个长度为1的分隔符 \ 。

举个栗子:dir \n\tdir1 \n\tdir20 \n\t\tfile.ext  意思是:dir目录下有两文件夹dir1和dir20,其中dir20目录下有文件file.ext。

dir\dir20\ tfile.ext 最长绝对路径为17+2=19。


算法:

public int lengthLongestPath(String input) {
		List<Integer> lenOfLevel = new ArrayList<Integer>();
		int max = 0, level = 0, preIdx = 0;
		input = input + '\n';//使得每个路径token后都接一个\n,便于统一处理
		boolean isFile = false;

		for (int i = 0; i < input.length(); i++) {
			if (input.charAt(i) == '.') {// 当前路径是否包含文件
				isFile = true;
			}
			if (input.charAt(i) != '\n') // 换一行
				continue;

			int tokenLen = i - preIdx + 1;//一个目录token的长度
			int tmp = tokenLen;
			if (level - 1 >= 0) {// 如果当前路径有上一层
				tmp += lenOfLevel.get(level - 1);// 则绝对路径长度需要加上上一层绝对路径长度
			}

			if (level <= lenOfLevel.size() - 1)// 当前路径有比它更深层的路径
				lenOfLevel.set(level, tmp);
			else
				lenOfLevel.add(tmp);// 当前路径是目前遇到的最深的路径

			if (isFile) {// 当前绝对路径包含文件,则是一条可以计算长度的有效路径
				max = Math.max(max, tmp);// 更新max
				isFile = false;
			}

			int nIdx = i;// 更新待计算token的level
			i++;
			while (i < input.length() && input.charAt(i) == '\t') {
				i++;
			}
			level = i - nIdx - 1;
			preIdx = i;// 更新待计算token的起始位置
		}
		return max - 1 >= 0 ? max - 1 : 0;
	}