GfG QA is closing soon... Please refer PRACTICE or GfG now on wards !!

Google interview Question (This is the a question from recent google interview can i get solution for this in JAVA)

You are given a listing of directories and files in a file system. Each directory and file has a name, which is a non-empty
string consisting of alphanumerical characters. Additionally, the name of each file contains a single dot character; the part
of the name starting with the dot is called the extension. Directory names do not contain any dots. All the names are case-
sensitive.
Each entry is listed on a separate line. Every directory is followed by the listing of its contents indented by one space
character. The contents of the root directory are not indented.
Here is a sample listing:
dir1
 dir11
 dir12
  picture.jpeg
  dir 121
   file1.txt
dir2
 file2.gif
We have three files (picture.jpeg, file1.txt and file2.gif) and six directories (dir1, dir11, dir12, dir121, dir2 and the
root directory). Directory dir12 contains two files (picture.jpeg and file1.txt) and an empty directory (dir121). The root
directory contains two directories (dir1 and dir2).
The absolute path of a directory is a string containing the names of directories which have to be traversed (from the root
directory) to reach the directory, separated by slash characters. For example, the absolute path to the directory dir121 is
dir1/dir12/dir121". Note that there is no "drive letter", such as "C: ", and each absolute path starts with a slash. The
absolute path of a root directory is The image files are the files with extensions .jpeg, .png or .gif (and only these extensions). We are only interested in directories that directly contain image files (that is, without looking in their subdirectories). We want to find the total length
of the absolute paths to all the directories that directly contain at least one image file. For example, in the file system
described above there are two directories that directly contain image files: "/dir1/dir12" and "Mia". Directory "/dir1"
doesn't directly contain any image files. The total length of the absolute paths "/dir1/dir12" and "/dir2" is 11 + 5 = 16.
Write a function:

int solution(char *S);

that, given a string S consisting of N characters which contains the listing of a file system, returns the total of lengths (in
characters) modulo 1,000,000,007 of the absolute paths to all the directories directly containing at least one image file. For
example, given the sample listing shown above, the function should return 16, as explained above. If there are no image
files in the listing, the function should return 0.
Assume that:
N is an integer within the range [1..3,000,000];
string S consists only of alphanumerical characters (a-z and/or A-Z and/or 0-9), spaces, dots (.) and end-
of-line characters;
string S is a correct listing of a file system contents.

Complexity:
expected worst-case time complexity is 0(N);
expected worst-case space complexity is 0(N) (not counting the storage required for input arguments).

asked Mar 5, 2016 by Nikhil Bharadwaj

would appreciate clean explanation format

Could you please provide a sample input string? There are many things that are not clear from the explanation.

19 Answers

namespace ConsoleApplication1
{
    public class Program
    {
        // second question
        public static int solution2(string s)
        {
            int length = 0, fileNum = 0;
            string allDir = "", lastDir = "";
            string[] eachdir = s.Split(new string[] { "\n" }, StringSplitOptions.None);
            int countOfSpace = 0;
            bool getThisDir = false;

            for (int i = 0; i < eachdir.Length; i++)
            {
                if (eachdir[i].Contains(".jpeg") || eachdir[i].Contains(".gif"))
                {
                    fileNum++;
                    countOfSpace = numSpace(eachdir[i]);
                    getThisDir = false;
                    for (int j = i-1; j >= 0; j--)
                    {
                        if (numSpace(eachdir[j]) != numSpace(lastDir))
                        {
                            getThisDir = false;
                        }
                        if (numSpace(eachdir[j]) >= countOfSpace)
                        {
                            continue;
                        }
                        if (countOfSpace == 0)
                        {
                            break;
                        }

                        if (eachdir[j].Contains(getSpace(countOfSpace - 1)) && getThisDir == false && !eachdir[j].Contains("."))
                        {
                            if (getSpace(countOfSpace - 1) == "")
                            {
                                allDir += eachdir[j] + "\\";
                            }
                            else
                            {
                                allDir += eachdir[j].Replace(getSpace(countOfSpace - 1), "") + "\\";
                            }
                            countOfSpace -= 1;
                            getThisDir = true;
                            lastDir = eachdir[j];
                        }
                    }
                }
            }

            foreach (char c in allDir)
            {
                if (c == '\\')
                {
                    continue;
                }

                length++;
            }

            return length - fileNum;
        }

        public static string getSpace(int num)
        {
            string s = "";
            if (num < 0)
            {
                return "";
            }
            for (int i = 1; i <= num; i++)
            {
                s += " ";
            }

            return s;
        }

        public static int numSpace(string s)
        {
            int count = 0;
            string space = " ";
            for (int i = 0; i < s.Length; i++)
            {
                if (s.Contains(space))
                {
                    count++;
                }
                space += " ";
            }

            return count;
        }


        public static void Main(string[] args)
        {
            string listDir = "dir1\n dir11\n dir12\n  picture.jpeg\n  dir121\n   file1.txt\ndir2\n file2.gif";
           
            // Keep the console window open in debug mode.
            Console.WriteLine(solution2(listDir));
            Console.ReadKey();
        }
    }
}

C# actually. Not a good way though

answered Mar 19, 2016 by anonymous

After analyzing the requirement, here is my solution:

public static int printSum(String s){
       String[] arr=s.split("\n");
       int sum=0, spaces=0;
       for(int i=arr.length-1;i>=0;i--){
           String line=arr[i];
           if(line.contains(".gif") | line.contains(".jpeg") ){
               spaces=line.length()-line.trim().length();
           }
           if(spaces> line.length()-line.trim().length() ){
               sum+=line.trim().length()+1;
               spaces--;

             sum++;
           }
       }
       return sum;
}

answered Jun 6, 2016 by Shishir.n 2 flags

Good one man! I like the solution. 

Can you explain why used sum++ in last line? 

Lol. You copied my solution word for word. Not cool man! not cool!

This is my solution in JAVA. I didn't ample test it though.

public int solution (String S) {
	String[] tokens = S.split("\n");
	int length_sum = 0;
	for(int i = tokens.length - 1, spaces = 0; i >= 0; i--) {
		if(tokens[i].contains("jpeg") || tokens[i].contains("gif") || tokens[i].contains("png"))
			spaces = tokens[i].length() - tokens[i].trim().length();
		if(!tokens[i].contains(".") && (tokens[i].length() - tokens[i].trim().length() + 1) == spaces) {
			length_sum += tokens[i].trim().length() + 1;
			spaces--;
		}
	}
	return length_sum;
}

 

answered Mar 28, 2016 by anonymous
edited Mar 28, 2016

Here is the solution in c#. It solves the crux of the problem. But does not take inputs in the afore mentioned format. http://ideone.com/uA0Sbs 

answered Mar 12, 2016 by cp

Last login: Sat May  7 17:42:32 on ttys001

Yus-MacBook-Pro:programming Claude$ ls 

a.out        checksize.c    findMissing.c    linkListAdder.c    practice.c    test.c        testtest.c

atoi.c        findMax.c    hashfunction.c    practice    stack.c        test2.c        uniquestring.c

Yus-MacBook-Pro:programming Claude$ vim 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

        struct strBucket* next;

}strBucket; 

 

strBucket* splitStr(char* str){

        if (str == NULL) {

                printf("Invalid path\n");

                return NULL; 

        }

        char* temp;

        strBucket *head, *node; 

        node = NULL; 

        temp = strtok(str, "\n");

        while (temp != NULL){

                head = (strBucket*)malloc(sizeof(strBucket)*1);

                head->str = temp;

                head->next = node; 

                node = head;                        

                temp = strtok(NULL, "\n");

        }

        return head; 

}

 

int countSpace(char* str){

        int count = 0; 

        while(str[count] == ' '){

                count++; 

        }        

        return count;

}

 

 

int calTotalLen(char* str){

        strBucket* head = splitStr(str);

        int space = 0; 

        int totLen = 0;   

        while (head !=NULL){

                if(strstr(head->str,"jpeg")!=NULL||strstr(head->str,"png")!=NULL||strstr(head->str,"gif")!=NULL){

                        space = countSpace(head->str);

                }

                if(strchr(head->str,'.')==NULL && (countSpace(head->str)+1)== space){

                        totLen = totLen + strlen(head->str) - space + 2; 

                        space--; 

                }

                head = head->next; 

        }

        return totLen; 

}

 

int main(){

        char c[80] = "dir1\n dir11\n dir12\n  picture.jpeg\n  dir121\n   file1.txt\ndir2\n file2.gif\n";

        int len = calTotalLen(c);

        printf("The total length is %d\n",len);

        return 0; 

}

 

answered May 8, 2016 by Cloudyxz

Lol for guy who wrote 100 lines of code! You will not pass an interview if you solve this problem with more than 15 lines of code.

Here is an elegant solution in Java:

 public static int printSum(String s){
        String[] arr=s.split("\n");
        int sum=0, spaces=0;
        for(int i=arr.length-1;i>=0;i--){
            String line=arr[i];
            if(line.contains(".gif") | line.contains(".jpeg") ){
                spaces=line.length()-line.trim().length();
            }
            if(spaces> line.length()-line.trim().length() ){
                sum+=line.trim().length()+1;
                spaces--;
            }
        }
        return sum;
 }

 

answered Jun 3, 2016 by dark_knight

My answers don't represent Google in any way, shape or form. As far as your stock goes, do as you please. You won't be missed. 

Google hiring decisions are made purely on your technical problem solving skills not on your communication or people's skills. If you need a job where you are judged solely on your communication skills, then Google is not a place for you, nor is Apple nor Amazon, nor Facebook, nor Palantir, nor Microsoft.

Truly the simplest solution! At first, thought that it was complex and required the use of regular expressions.

what is two image on the same dir(with the same indent). this can only calculate one.

Seems second if where spaced are added to sum will never be true?  

dir1
 dir11
 dir12
  picture.jpeg  //  14  - 12 = 2      ( since 2 < 12, it fails second if check)
  dir 121
   file1.txt
dir2
 file2.gif    // 10 - 9 = 1     (  this too fails  second if check )    so sum will be returned as  0  or am I missing something?

This solution does not account for multiple images in a directory.

Eg:
This solution will not work for

dir1
 dir11
 dir12
  picture.jpeg
  picture2.jpeg
  dir 121
   file1.txt
dir2
 file2.gif 

 OR this one

 

dir1
 dir11‚Äč
 image.jpeg
 dir12
  picture.jpeg
  dir 121
   file1.txt
dir2
 file2.gif 

 

 

public static int printSum(String s){
       String[] arr=s.split("\n");
       int sum=0, spaces=0, multiplier=1;
       for(int i=arr.length-1;i>=0;i--){
           String line=arr[i];
           if(line.contains(".gif") | line.contains(".jpeg") ){
               if(space > 0) {
                  multiplier++;
               } else {
                  spaces=line.length()-line.trim().length();   
               }
           }
           if(spaces> line.length()-line.trim().length() ){
               sum+=line.trim().length()+1 * multiplier;
               spaces--;
               if(spaces == 0) {
                   multiplier = 1;
               }
           }
       }
       return sum;
}

For this you need a multiplier aswell 

 

 

What would be the most efficient way to do this, if we were to find the total length of all absolute paths to the image files?
answered Jul 3, 2016 by ian26

Java solution using Stack to keep track of directory level.

class Directory {
    String fileName;
    int level;
    int currLength;
}

public class AbsoluteImagePathLength {
    public static void main(String[] args) {
        AbsoluteImagePathLength obj = new AbsoluteImagePathLength();
        String S = "dir1\n dir11\n dir12\n  picture.jpeg\n  dir121\n  file1.txt\ndir2\n file2.gif";
        int len = obj.getPathSum(S);
        System.out.println(len);
    }


    public int getPathSum(String s){
        String[] dirs = s.split("\n");
        Stack<Directory> stack = new Stack<>();              //Only push directories to stack

        int maxLen = 0;
        for(String dir : dirs) {

            int currLevel = 0;
            while (dir.charAt(currLevel) == ' ')            //calculate current level by counting spaces
                currLevel++;

            String name = dir.substring(currLevel);      //substring except space

            if (name.contains(".")) {      //File
                if (name.contains(".jpeg") || name.contains(".gif") || name.contains(".png")) {  //img file
                    if(stack.peek().level == currLevel){                        //checks if another dir found at same level, then remove previous dir
                        stack.pop();
                    }
                    int absLength = (stack.isEmpty() ? 1 : stack.peek().currLength + 1) + name.length();
                    maxLen += absLength;
                }
            } else {      //Dir
                while (!stack.isEmpty() && stack.peek().level >= currLevel) {   //checks if another dir found at same level, then remove previous dir
                    stack.pop();
                }

                Directory directory = new Directory();
                directory.fileName = name;
                directory.level = currLevel;
                directory.currLength = (currLevel == 0 ? 1 : stack.peek().currLength + 1) + name.length();

                stack.push(directory);
            }
        }
        return maxLen;
    }
}

 

answered Aug 6, 2016 by SandeepK

Hi all, here is my Java Solution with few tests included to test directly using "Run on IDE" button.

public class UnqAbsImgPaths {
    public static void main(String[] args) {
        String pathLists1 = "dir1\n dir11\n dir12\n  picture.jpeg\n  dir121\n  file1.txt\ndir2\n file2.gif";
        String pathLists2 = "dir1\n dir11\n dir12\n  picture.jpeg\n  dir121\n  file1.png\ndir2\n file2.gif";
        String pathLists3 = "dir1\n dir11\n dir12\n  picture.jpeg\n  dir121\n   file1.png\ndir2\n file2.gif";
        String pathLists4 = "dir1\n dir11\n dir12\n  dir121\n  file1.txt\ndir2";
        String pathLists5 = "";

        System.out.println("length of pathLists1 is: " + solution(pathLists1));
        System.out.println("length of pathLists2 is: " + solution(pathLists2));
        System.out.println("length of pathLists3 is: " + solution(pathLists3));
        System.out.println("length of pathLists4 is: " + solution(pathLists4));
        System.out.println("length of pathLists5 is: " + solution(pathLists5));
    }

    static int solution(String S) {
        String[] files = S.split("\n");
        String unqAbsImgPaths = "";
        for (int i = 0; i < files.length; i++) {
            String fName = files[i], absImgPath = "";
            if (fName.endsWith(".jpeg") || fName.endsWith(".png") || fName.endsWith(".gif")) {
                int j = i;
                do {
                    int spacesCurr = files[j].length() - files[j].trim().length();
                    int spacesPrev = files[j - 1].length() - files[j - 1].trim().length();
                    if (spacesCurr > spacesPrev) {
                        absImgPath = "/" + files[--j].trim() + absImgPath;
                        if (spacesCurr == 0 || spacesPrev == 0) {
                            break;
                        }
                    }
                    j--;
                } while (j > 0);
                if (!unqAbsImgPaths.endsWith(absImgPath)) {
                    unqAbsImgPaths += absImgPath;
                }
            }
        }
        return unqAbsImgPaths.length();
    }
}

 

answered Aug 6, 2016 by ramanand.patil
edited Aug 6, 2016 by ramanand.patil

Somehow this is not giving correct answer on GFG IDE.

How is it O(n)?
import java.util.Stack;

public class Solution {
	public class Files {
		public Files(String file, int i, int j) {
			this.fileName = file;
			this.length = i;
			this.noOfSpaces = j;
		}
		String fileName;
		int length;
		int noOfSpaces;
	}
	Stack<Files> files = new Stack<Files>();
	
	public void solution(String S) {
		int sum = 0;
		String[] splitStr = S.split("\n");
		int noOfSpaces = splitStr[0].length() - splitStr[0].trim().length();
		files.push(new Files(splitStr[0], splitStr[0].trim().length() + 1, noOfSpaces));
		for(int i = 1; i < splitStr.length; i++) {
			if(noOfSpaces < splitStr[i].length() - splitStr[i].trim().length()) {
				noOfSpaces = splitStr[i].length() - splitStr[i].trim().length();
				files.push(new Files(splitStr[i], files.peek().length + splitStr[i].trim().length() + 1, noOfSpaces));
			} else {
				while(!files.isEmpty() && files.peek().noOfSpaces >= splitStr[i].length() - splitStr[i].trim().length()) {
					files.pop();
				}
				noOfSpaces = splitStr[i].length() - splitStr[i].trim().length();
				if(files.empty())
					files.push(new Files(splitStr[i], splitStr[i].trim().length() + 1, noOfSpaces));
				else
					files.push(new Files(splitStr[i], files.peek().length + splitStr[i].trim().length() + 1, noOfSpaces));
			}
			if (splitStr[i].contains(".gif") || splitStr[i].contains(".jpeg")) {
				sum += files.peek().length;
			}
		}
		System.out.println(sum);
	}

	public static void main(String args[]) {
		Solution s = new Solution();
		//String S = "dir1\n dir11\n dir12\n  picture.jpeg\n  dir121\n  file1.txt\ndir2\n file2.gif";
		String S = "dir1\n dir11\n  dir111\n   picture.gif\n   text1.txt\n  dir112\n   sample1.jpeg\n dir12\n  sample2.gif";
		s.solution(S);
	}
}

 

answered Aug 7, 2016 by Ashish Bhumkar
...