package com.interview.recursion;

import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

/**
 * Find longest absolute path in file system indicated by \n and \t.
 *
 * Solution:
 * Create queue of file and its level. Then recurse from root towards file. Use level
 * to decide if next word in queue is in same level (so no more recursion) or next level so
 * going deep in recursion.
 *
 * Time complexity O(n)
 * Space complexity O(n)
 *
 * https://leetcode.com/problems/longest-absolute-file-path/
 */
public class LongestAbsolutePath {
    public int lengthLongestPath(String input) {
        if (input.length() == 0) {
            return 0;
        }
        StringTokenizer tokenizer = new StringTokenizer(input, "\n");
        Queue<Node> queue = new LinkedList<>();
        while (tokenizer.hasMoreTokens()) {
            queue.offer(new Node(tokenizer.nextToken()));
        }
        Node root = new Node("", -1);
        return lengthLongestPath(queue, root, 0);
    }

    public int lengthLongestPath(Queue<Node> queue, Node root, int currentLength) {
        if (root.isFile) {
            return currentLength + root.level;
        }
        if (queue.isEmpty()) {
            return 0;
        }
        int max = 0;
        while (!queue.isEmpty()) {
            Node n = queue.peek();
            if (root.level < n.level) {
                queue.poll();
                max = Math.max(max, lengthLongestPath(queue, n, n.file.length() + currentLength));
            } else {
                break;
            }
        }
        return max;
    }

    class Node {
        String file;
        int level;
        boolean isFile;
        Node(String file, int level) {
            this.file = file;
            this.level = level;
        }
        Node(String file) {
            int numberOfTabs = 0;
            int i;
            for (i = 0; i < file.length(); i++) {
                if (file.charAt(i) == '\t') {
                    numberOfTabs++;
                } else {
                    break;
                }
            }
            this.file = file.substring(i);
            this.level = numberOfTabs;
            this.isFile = file.contains(".");
        }
    }
}

@@ -80,16 +80,40 @@
 .Queue;%0A
+import java.util.Stack;%0A
 import j
@@ -138,16 +138,16 @@
 enizer;%0A
-
 %0A/**%0A * 
@@ -226,16 +226,18 @@
 Solution
+ 1
 :%0A * Cre
@@ -439,16 +439,382 @@
 ion.%0A *%0A
+ * Solution 2(iterative):%0A * Keep pushing elements into stack till you either reach a file with . or a file whose number of tabs is less than%0A * top of stack. If you reach file with extension then update the max. Otherwise keep popping from stack till number of tabs%0A * at top of stack becomes less than current file. Maintain current length during push and pop.%0A *%0A
  * Time 
@@ -2597,24 +2597,24 @@
 tains(%22.%22);%0A
-
         %7D%0A  
@@ -2616,11 +2616,1221 @@
  %7D%0A    %7D
+%0A%0A    public int lengthLongestPathIterative(String input) %7B%0A        if (input.length() == 0) %7B%0A            return 0;%0A        %7D%0A        String%5B%5D tokens = input.split(%22%5Cn%22);%0A        Stack%3CString%3E stack = new Stack%3C%3E();%0A        Stack%3CInteger%3E stack1 = new Stack%3C%3E();%0A        int len = 0;%0A        int max = 0;%0A        for (String token : tokens) %7B%0A            int level = 0;%0A            int i;%0A            for (i = 0; i %3C token.length(); i++) %7B%0A                if (token.charAt(i) == '%5Ct') %7B%0A                    level++;%0A                %7D else %7B%0A                    break;%0A                %7D%0A            %7D%0A            token = token.substring(i);%0A            while (!stack1.isEmpty() && level %3C= stack1.peek()) %7B%0A                stack1.pop();%0A                String data = stack.pop();%0A                len -= data.length() + 1; //+1 to account for '%5C' between folders files%0A            %7D%0A            if (token.contains(%22.%22)) %7B%0A                max = Math.max(max, len + token.length());%0A            %7D else %7B%0A                stack1.push(level);%0A                stack.push(token);%0A                len += token.length() + 1; //+1 to accoutn for '%5C' between folders files%0A            %7D%0A        %7D%0A        return max;%0A    %7D
 %0A%7D%0A

Add another method in longest absolute path