Flipkart Interview Question for SDE-2s


Country: India




Comment hidden because of low score. Click to expand.
2
of 4 vote

I'd use a trie build from the list of given words. Start from the given string such as "mobilelg" Look for a complete word. When found split the word and start from the found index. eg if mobile is in the dictionary trie, start from index 5 from the root of the trie. repeat until all the chars covered or not found.

- fuubar August 21, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 2 votes

That seems intuitive, but isn't actually correct. Consider the following example:

Dictionary words: flip, flipper, dolphin
String: flipperdolphin

With your approach, you would see "flip" and consider it a word. You would then be left with perdolphin, which cannot be split into dictionary words. However, if you had taken the split "flipper dolphin", you would have found a solution.

Our preference for splitting words as early as possible does not imply that the earliest split is always correct, because the earliest possible split does not always lead to a valid solution. We therefore cannot take the direct greedy approach you're taking.

- eugene.yarovoi August 21, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I agree with @eugene and also with @given-test . This solution will give trouble when a string and its substring both are present in the dictionary as valid words. Hence I propose following solution:
when a valid split position is found check if substring from char after previous valid pos till this split pos exists in dictionary. If it does then this split position is a valid split pos else not. This way keep an array of all valid split pos and finally display the words.

- pavi.8081 August 22, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

This question you asked is from flipkart's interview street coding round....
You can find the correct solution at geeks for geeks... There search for split sentence (using dynamic programming) . solution there needs a little modification to print the split up words and also you need to add condition to check if sub string of a string and the string both lie in dictionary. This case is not covered in any solution found over net.

- given-test August 21, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

There is one more requirement / property that algorithm should satisy which I missed in above question :
4. If there is no match based on mentioned 3 properties / requirements, then output should be "NULL". For eg.,

Assume you are given the following list of words : mobile, flip, kart, flipkart and user-input query string is flipkartmobilenotpresent. In this case, the answer / output should be "NULL" as no split-up is possible based on given dictionary words.

- nilukush August 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I implemented it using the following algorithm :
1. For each dictionary word, find the index of all occurences in query string (could be repetitions of dictionary words in query string as explained). Add this index and corresponding word in a map.

2. After this, there will be a map with indexes of all occuring dictionary words in query string.

3. Iterate through map (since map will have its keys sorted in C++) take each word and concatenate it. If the result of concatenation is not query string then, output "NULL".

At the same time, concatenate each word from map with space. In the event that result from above equals query string, then output this concatenation of words with spaces.

Following is the code snippet :

#include <iostream>
#include <deque>
#include <string>
#include <map>

namespace
{
    static const size_t& MAX_QUERY_LENGTH(500);
}

int main() {
    /* Enter your code here. Read input from STDIN. Print output to STDOUT */
    std::size_t dict_size;
    std::deque<std::string> dict;
    std::string query;
    std::string output("NULL");

    // read input
    std::cin >> dict_size;
    for(std::size_t i(0); i < dict_size; ++i)
    {
        std::string word;
        std::cin >> word;
        dict.push_back(word);
    }

    // limit query string to allowed MAX_QUERY_LENGTH
    std::cin >> query;
    if(query.size() > MAX_QUERY_LENGTH)
    {
        query.erase(MAX_QUERY_LENGTH);
    }

    std::map<std::size_t, std::string> index_word_map;
    for(std::deque<std::string>::const_iterator dict_iter(dict.begin()), dict_end(dict.end()); dict_iter != dict_end; ++dict_iter)
    {
        std::string::size_type pos(0);
        for(;(pos = query.find(*dict_iter, pos)) != std::string::npos;)
        {
            std::map<std::size_t, std::string>::iterator iwm_iter(index_word_map.find(pos));
            if(iwm_iter == index_word_map.end())
            {
                index_word_map.insert(std::make_pair<std::string::size_type, std::string>(pos, *dict_iter));
            }
            else
            {
                std::string& word(iwm_iter->second);
                if(word.size() > dict_iter->size())
                {
                    word = *dict_iter;
                }
            }

            pos += dict_iter->size();
        }
    }

    std::string present, splitup;
    for(std::map<std::size_t, std::string>::iterator iwm_iter(index_word_map.begin()),
        iwm_end(index_word_map.end()); iwm_iter != iwm_end; ++iwm_iter)
    {
        present += "" + iwm_iter->second;
        splitup += iwm_iter->second + " ";
    }

    if(present == query)
    {
        output = splitup;
    }

    std::cout << output;

    return 0;
}

- nilukush August 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

This won't work because there can be multiple dictionary words that start at the same index. Consider "flipper" and a dictionary of {"flipper", "flip"}.

- eugene.yarovoi August 30, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 2 vote

/**
 * Logic is
 * Process the dictionary into trie
 * String[] array = {"Flip","Kart","Mobile","lc"};
 * to trie
 *
 * Process the queryString "flipkartmobile" as mentioned below
 * f
 * fl
 * fli
 * flip
 * k
 * ka
 * kar
 * kart
 * m
 * mo
 * mob
 * mobi
 * mobil
 * mobile
 *
 *If there is a match add it to targetString and append one tab
 *
 * i/p : flipkartmobile
 * o/p : flip	kart	mobile	
 *
 * i/p : flipkartmobilelclc
 * o/p : flip	kart	mobile	lc	lc
 */

public class KartExample {
    public KartExample() {
        super();
    }

    public static void main(String[] args) {
        KartExample kartExample = new KartExample();
        String[] array = { "Flip", "Kart", "Mobile", "lc" };
        KartExample.Trie trie = kartExample.new Trie();
        for (String str : array) {
            trie.insert(str);
        }
        String queryString = "flipkartmobilelclc";
        int j = 0;
        boolean find = false;
        String targetString = "";
        if (queryString.length() < 500) {
            for (int i = 0; i < queryString.length(); i++) {
                //            System.out.println(queryString.substring(j,i+1));
                find = trie.search(queryString.substring(j, i + 1));
                if (find) {
                    targetString = targetString + queryString.substring(j, i + 1) + "\t";
                    j = i + 1;
                }
            }
            System.out.println(targetString);
        }
    }

    class Trie {
        private Trie[] trieArray;
        private char data;
        private int now;
        private boolean word;
        private Trie root;

        public Trie() {
            this.setData(' ');
            this.setTrieArray(new Trie[26]);
        }

        public Trie(char data) {
            this.setData(data);
            this.setTrieArray(new Trie[26]);
        }

        public boolean search(String pattern) {
            Trie root = this.getRoot();
            if (this.getRoot() == null) {
                return false;
            }
            for (int i = 0; i < pattern.length(); i++) {
                if (root.getTrieArray()[atoi(pattern.charAt(i))] == null) {
                    return false;
                }
                root = root.getTrieArray()[atoi(pattern.charAt(i))];
            }
            return root.isWord();
        }

        public void insert(String item) {
            Trie root = this.getRoot();
            if (this.getRoot() == null) {
                root = new Trie();
                this.setRoot(root);
            }
            for (int i = 0; i < item.length(); i++) {
                if (root.getTrieArray()[atoi(item.charAt(i))] == null) {
                    root.getTrieArray()[atoi(item.charAt(i))] = new Trie(item.charAt(i));
                }
                root = root.getTrieArray()[atoi(item.charAt(i))];
            }
            root.setWord(true);
            root.setNow(root.getNow() + 1);

        }

        public int atoi(char ch) {
            int i = 0;
            if (ch >= 65 && ch <= 90)
                i = ch - 65;
            else if (ch >= 97 && ch <= 122)
                i = ch - 97;
            else
                i = (int)ch;
            return i;

        }


        public void setTrieArray(Trie[] trieArray) {
            this.trieArray = trieArray;
        }

        public Trie[] getTrieArray() {
            return trieArray;
        }

        public void setData(char data) {
            this.data = data;
        }

        public char getData() {
            return data;
        }

        public void setNow(int now) {
            this.now = now;
        }

        public int getNow() {
            return now;
        }

        public void setWord(boolean word) {
            this.word = word;
        }

        public boolean isWord() {
            return word;
        }

        public void setRoot(Trie root) {
            this.root = root;
        }

        public Trie getRoot() {
            return root;
        }
    }

}

- Prakash August 21, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I think both prefix and suffix processing will fix the issue

- Prakash August 22, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

This code will fix the issue

public static void main(String[] args) {
        KartExample kartExample = new KartExample();
        String[] array = { "Flip", "Kart","Mobile","Flipper", "Dolphin", "lc" };
        KartExample.Trie trie = kartExample.new Trie();
        for (String str : array) {
            trie.insert(str);
        }
//        String queryString = "flipperflipperfliplcdolphin";
        String queryString = "flipperkartmobilelclcdolphin";
        int j = 0;
        boolean find = false;
        String targetString = "";
        if (queryString.length() < 500) {
            for (int i = 0; i < queryString.length(); i++) {
//                                System.out.println(queryString.substring(j, i + 1));
                find = trie.search(queryString.substring(j, i + 1));
                if (find) {
                    targetString = targetString + queryString.substring(j, i + 1) + "\t";
                    j = i + 1;
                }
            }
            j = 0;
            System.out.println(targetString);
            String queryString1 = queryString;
            targetString = "";
            for (int i = queryString1.length(); i >= 0; i--) {
//                System.out.println(queryString1.substring(i));
                j++;
                find = trie.search(queryString1.substring(i));
                if (find) {
                    targetString = queryString1.substring(i) + "\t" + targetString;
                    queryString1 = queryString1.substring(0, queryString.length() - j + 1);
                }
            }
            System.out.println(targetString);
        }

- Prakash August 22, 2013 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

The new revision isn't correct either. There's no reason why parsing from either the front or the back greedily would be correct. There are some cases for which it happens to be right, but add "pper" to your array variable and you'll see wrong output.

- eugene.yarovoi August 28, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Thanks For figuring the issue.

I got ur point.

- Prakash August 30, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Following Code works perfectly:

public class SplitWords {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		String[] dict={"jungleegames","that","what","is"};
		String query="thatjungleegameswhatisthat";
		String query1;
		int index;
		int beginIndex=0;
		for(String s: dict){
			if(query.contains(s)){
			beginIndex=query.indexOf(s);
			index=beginIndex+s.length();
			System.out.println("BeginIndex=" + beginIndex + " " + s+ " Index=" + index);
			
				query1=query.substring(beginIndex,index);
				if(beginIndex!=0){
					
				
					
					query= query.substring(0,beginIndex)+ query1 + " " + query.substring(index);
					beginIndex=index;
				}
					else
					{
						query=query1+" " +  query.substring(index);
					}
			//	beginIndex=index;
			
		}
		
	}
		
		System.out.println(query);
	}
}

- devenster August 22, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

This is not gona work. Lets suppose ur input is thatjungleegameswhatisthatwhat. you code will divide by that jungleegames what is thatwhat. Repetition of words not handled.
Also what if i add "flipper, flip" to dictionary and string is flipper. You will divide it as "flip per"

- Anonymous September 07, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Above comment was for @ devenster

- Anonymous September 07, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

why we are not solving this problem by storing dictionary words in reverse order (in trie) and check input query string from last charecter..

- Sangram September 07, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

suppose Dictionary words are Dictionary words: flip, flipper, dolphin
input String is : flipperdolphin

it will get stored in trie in following manner
pilf,reppilf,nihplod.

if we check in reverse order first it will found 'dolphin' then 'flipper'.

- Sangram September 07, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include <iostream>
using namespace std;
#include <vector>
#include <map>
#include <set>
#include <string>


void PopulateDictionary(std::set<string>& dict)
{
dict.insert("ab");
dict.insert("ba");
dict.insert("abab");
dict.insert("baba");
dict.insert("Flip");
dict.insert("kart");
dict.insert("Flipkarted");
dict.insert("Mobile");
dict.insert("A");
dict.insert("Apple");
dict.insert("Pie");
dict.insert("i");
}
typedef std::vector<string> StringVec;
bool FindPossibleWords(unsigned int strRemaining, unsigned int strSize, std::map<int, std::vector<string>>& HashMap, StringVec& strVec)
{
if (strRemaining == strSize)
return true;
if (HashMap.find(strRemaining) == HashMap.end())
return false;
StringVec words = HashMap[strRemaining];
for (unsigned int i = 0; i < words.size(); i++)
{
if (FindPossibleWords(words[i].size() + strRemaining,
strSize,
HashMap, strVec))
{
strVec.insert(strVec.begin(), words[i]);
return true;
}
}
return false;
}
int main()
{
string str("ApplePie");
unsigned int strSize = str.size();
std::set<string> dict;
std::map<int, std::vector<string>>HashMap;

PopulateDictionary(dict);


for (unsigned int i = 0; i < strSize; i++)
{
for (unsigned int j = i + 1; j < strSize; j++)
{
string sub = str.substr(i,j-i+1);
if (dict.find(sub) != dict.end())
{
//insert in hash map
HashMap[i].push_back(sub);
}
}
}

StringVec finalWords;
bool found = FindPossibleWords(0, strSize, HashMap, finalWords);
if (found)
{
for (unsigned int i = 0; i < finalWords.size(); i++)
cout<<finalWords[i]<<endl;
}
else
{
cout<<"No appropriate word was found\n";
}

return 0;
}

- Anonymous September 24, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Its worked for me:

public static string ChangeInputString(string searchKeyword = "flipkartmobilesearch")
{
string modifiedSearchKey = string.Empty;
Dictionary<string, string> keywords = new Dictionary<string, string>();
keywords.Add("search", "search");
keywords.Add("flip", "flip");
keywords.Add("kart", "kart");
keywords.Add("mobile", "mobile");
keywords.Add("dummy", "dummy");
Dictionary<string, string> tempkeywords = keywords;

for (int i = 0; i < tempkeywords.Keys.Count && searchKeyword.Length>0; i++)
{
var item = tempkeywords.ElementAt(i);
if (searchKeyword.StartsWith(item.Value))
{
searchKeyword=searchKeyword.Substring(item.Value.Length, searchKeyword.Length-item.Value.Length);
modifiedSearchKey = modifiedSearchKey+item.Value + " ";
tempkeywords.Remove(item.Key.ToString());
i = -1;
}
}
return modifiedSearchKey.TrimEnd();//flip kart mobile search
}

- Bharath September 18, 2014 | Flag Reply


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More