The longest absolute path in file system

73 篇文章 1 订阅
8 篇文章 0 订阅

@(leetcode)[字符串|DFS|Google]
The string "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext" represents:

dir
    subdir1
    subdir2
    file.ext

a directory dir contains an empty sub-directories subdir1 and a sub-directory subdir2 containing a file file.ext.

The string "dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext"represents:

dir
    subdir1
        file1.ext
        subsubdir1
    subdir2
        subsubdir2
            file2.ext

a directory dir contains two sub-directories subdir1 and subdir2. subdir1 contains a file file1.extand an empty second-level sub-directory subsubdir1. subdir2 contains a second-level sub-directory subsubdir2 containing a file file2.ext.

We are interested in finding the longest(number of characters) absolute path to a file within our file system. That is, for example, in the second example above, the longest absolute path is "dir/subdr2/subsubdir2/file.ext", and its length is 30.

Given a string representing the file system in the above format, return the length of the longest absolute path to file in the abstracted file system. Simply put, that is the length of a valid path that ends with a file, and a file contains . and an extension.

Time complexity required: O(n) where n is the size of the input string.

Notice that a/aa/aaa/file1.txt is not the path you want, if there is aaaaaaaaaaaaaaaaaaaaa/sth.png.

Solution

#include <iostream>
#include <stack>
#include <string>
#include <cassert>

using namespace std;

//更新最长路径, 当扫描遇到 '\n'的时候说明已经处理完当前 depth的一个文件夹/文件
void update(stack<int>& len_st, int& current_len, int& depth,
            bool& is_file, int& res) {
  //比较len_st的深度与当前深度的关系, 如果len_st保存的深度大,则pop栈顶元素直到与当前深度depth相同
  while(len_st.size() > depth) {
    len_st.pop();
  }
  //如果栈不为空, 取出栈顶元素,表示在到当前层之间的长度,然后加上当前层的长度
  int len = ((len_st.empty()) ? 0 : len_st.top()) + current_len;
  if(is_file && len > res) {
    res = len;
  }
  len_st.push(len);
  current_len = depth = 0;
  is_file = false;
}

//其实这道题就是一个多叉树的深度遍历,并找到最深路径长度,转换成用字符串来表示,这样关键就是在于
//如果区分不同的层(递归深度),通过分析容易得出可以用\t的个数来表示目录深度。因此接下来就按照
//深度遍历的思路来搜索就可以了,算法的时间复杂度O(n) 空间复杂度O(n)
int get_longest_path(const string & path) {
  if(path.empty()) {
    return 0;
  }
  int res = 0, current_len = 0, depth = 0;
  bool is_file = false;
  //保存每层路径的长度,栈顶元素是当前搜索路径的长度
  stack<int> len_st;
  int str_len = path.size();
  for(int i = 0; i < str_len; ++i) {
      if(path[i] == '\n') {
        update(len_st, current_len, depth, is_file, res);
      } else if(path[i] == '\t') {
        //每识别一个\t目录的深度就增加1
        ++depth;
      } else {
        if(path[i] == '.') {
          is_file = true;
        }
        ++current_len;
      }
  }
  update(len_st, current_len, depth, is_file, res);
  return res;
}

void test() {
  {
    string str = "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext";
    assert(18 == get_longest_path(str));
  }

  {
    string str = "dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext";
    assert(29 == get_longest_path(str));
  }

  {
    string str = "a\n\tdir1\n\t\tdir2\n\t\t\tdir3\n\taaaaaaaaaaaaaaaaaaa.txt";
    assert(24 == get_longest_path(str));
  }
}

int main() {
  test();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值