Alien Dictionary | Practice | GeeksforGeeks

Given a sorted dictionary of an alien language having N words and k starting alphabets of standard dictionary. Find the order of characters in the alien language.
Note: Many orders may be possible for a particular test case, thus you may return any valid order and output will be 1 if the order of string returned by the function is correct else 0 denoting incorrect string returned.
 
Example 1:
Input: 
N = 5, K = 4
dict = {"baa","abcd","abca","cab","cad"}
Output:
1
Explanation:
Here order of characters is 
'b', 'd', 'a', 'c' Note that words are sorted 
and in the given language "baa" comes before 
"abcd", therefore 'b' is before 'a' in output.
Similarly we can find other orders.
Example 2:
Input: 
N = 3, K = 3
dict = {"caa","aaa","aab"}
Output:
1
Explanation:
Here order of characters is
'c', 'a', 'b' Note that words are sorted
and in the given language "caa" comes before
"aaa", therefore 'c' is before 'a' in output.
Similarly we can find other orders.

 
Your Task:
You don't need to read or print anything. Your task is to complete the function findOrder() which takes  the string array dict[], its size N and the integer K as input parameter and returns a string denoting the order of characters in the alien language.

Expected Time Complexity: O(N * |S| + K) , where |S| denotes maximum length.
Expected Space Compelxity: O(K)

Constraints:
1 ≤ N, M ≤ 300
1 ≤ K ≤ 26
1 ≤ Length of words ≤ 50
0
neeshumaini551 day ago
class Solution:
   	def findOrder(self,dict, N, K):
    # adjacency list for storing the key-value pair
    # of char in order of the list
    	adj = {c:set() for w in dict for c in w}
        for i in range(len(dict)-1):
            w1, w2 = dict[i], dict[i+1]
            minLen = min(len(w1), len(w2))
            if len(w1) > len(w2) and w1[:minLen] == w2[:minLen]:
            	return ""
        for j in range(minLen):
        	if w1[j] != w2[j]:
            	adj[w1[j]].add(w2[j])
               	break
       # postorder depth frist search
       	visit = {}
       	res = []
       	def dfs(c):
           	if c in visit:
               	return visit[c]
           	visit[c] = True
           	for nei in adj[c]:
               	if dfs(nei):
                   	return True
           	visit[c] = False
           	res.append(c)
      
       	for c in adj:
           	if dfs(c):
               	return ""
       	#print(adj)
       	res.reverse()
       	return ''.join(res)
0
lindan1236 days ago
void dfs(int i,vector<int>adj[] , vector<int>&vis,stack<int>&st){
        vis[i]=1;
        
        for(auto x : adj[i]){
            if(vis[x]==0){
                dfs(x,adj,vis,st);
            }
        }
        
        st.push(i);
        
    }
    
    string findOrder(string dict[], int n, int k) {
        vector<int> vec[k];
        
        for(int i=0;i<n-1;i++)
        {
            string s1 = dict[i];
            string s2 = dict[i+1];
            
            int m = min(s1.length(),s2.length());
            for(int j=0;j<m;j++)
            {
                if(s1[j]!=s2[j])
                {
                    vec[s1[j]-'a'].push_back(s2[j]-'a');
                    
                    break;
                }
            }
        }
        
        string ans = "";
        stack<int> st;
        vector<int> visited(k,0);
        for(int i=0;i<k;i++)
        {
            if(visited[i]==0)
            {
                dfs(i,vec,visited,st);
            }
            
        }
        
        while(!st.empty())
        {
            char c = st.top() + 'a';
            ans = ans + c;
            st.pop();
        }
        return ans;
    }
Time Taken : 0.29
Cpp
0
getkar1286 days ago
def findOrder(self,dict, N, K):
   # code here
       adj = {c:set() for w in dict for c in w}
       for i in range(len(dict)-1):
           w1, w2 = dict[i], dict[i+1]
           minLen = min(len(w1), len(w2))
           if len(w1) > len(w2) and w1[:minLen] == w2[:minLen]:
               return ""
           for j in range(minLen):
               if w1[j] != w2[j]:
                   adj[w1[j]].add(w2[j])
                   break
       visit = {}
       res = []
       def dfs(c):
           if c in visit:
               return visit[c]
           visit[c] = True
           for nei in adj[c]:
               if dfs(nei):
                   return True
           visit[c] = False
           res.append(c)
       
       for c in adj:
           if dfs(c):
               return ""
       res.reverse()
       return ''.join(res)
   
0
akashrajoria2501031 week ago
Can anyone tell me why my code isnt working?
class Solution{   public String findOrder(String [] dict, int n, int k)   {       ArrayList<Integer>[] adj = new ArrayList[n];       for (int i = 0; i < adj.length; i++) {           adj[i] = new ArrayList<>();       }       for (int i = 0; i < n-1; i++) {           String w1 = dict[i];           String w2 = dict[i+1];           for (int j = 0; j < Math.min(w1.length(),w2.length()); j++) {               if(w1.charAt(j)!=w2.charAt(j)){                   adj[w1.charAt(j)-'a'].add(w2.charAt(j)-'a');                   break;               }           }       }       boolean[] visited = new boolean[n];       String ans = "";       Stack<Character> s = new Stack<>();       for (int i = 0; i < k; i++) {           if(!visited[i]){               dfs(i,adj,visited,s);           }       }       while(!s.isEmpty()){           ans+= (char)(s.pop() + 'a');       }       return ans;   }   static void dfs(int cur,ArrayList<Integer>[] adj, boolean[] visited,Stack<Character> s){       visited[cur] = true;       for( int i : adj[cur]){           if(!visited[i]){               dfs(i, adj, visited, s);           }       }       s.push((char) (cur + 'a'));          }}
0
joyrockok2 weeks ago
class Solution{ArrayList<Integer> linkedList[];Stack<Integer> stack;boolean visit[];   public String findOrder(String [] dict, int N, int K)   {       // Write your code here    linkedList = new ArrayList[K];    stack = new Stack<Integer>();    visit = new boolean[K];        for(int i=0; i<K; i++) {     linkedList[i] = new ArrayList<Integer>();     visit[i]=false;    }        for(int i=0; i<N-1; i++) {     String str1 = dict[i];     String str2 = dict[i+1];          int min = Math.min(str1.length(), str2.length());     for(int j=0; j<min; j++) {      if(str1.charAt(j) != str2.charAt(j)) {       linkedList[str1.charAt(j)-'a'].add(str2.charAt(j)-'a');       break;      }           }    }        makeOrder(K);        String str="";    while(stack.isEmpty() != true) {     str = str + (char)(stack.pop()+'a');    }           return str;   }      public void makeOrderWords(int alpha) {    visit[alpha] = true;        for(Integer al : linkedList[alpha]) {     if(visit[al] == false)      makeOrderWords(al);    }        stack.add(alpha);   }      public void makeOrder(int K) {        for(int i=0; i<K; i++) {     if(visit[i] == false)      makeOrderWords(i);    }   }}
+1
shyamprakash8072 weeks ago
Python solution using Khan's Algorithm(Topology sort):
Time Taken : 0.78 / 2.61
 
from collections import dequeclass Solution:   def findOrder(self,d, N, K):   # code here       g = [[] for i in range(K)]       for i in range(n-1):           s1 = d[i]           s2 = d[i+1]           j = 0           while j < len(s1) and j < len(s2):               if s1[j] != s2[j]:                   g[ord(s1[j])-97].append(ord(s2[j])-97)                   break               j += 1       indeg = [0 for i in range(K)]       for i in range(K):           for j in g[i]:               indeg[j] += 1       q = deque()       st = []       for i in range(K):           if indeg[i] == 0:               q.append(i)       while len(q):           curr = q.popleft()           st.append(chr(curr+97))           for adj in g[curr]:               indeg[adj] -= 1               if indeg[adj] == 0:                   q.append(adj)       return st   
0
rainx3 weeks ago
Simple Topla karna hai....
void DFSRec(list<int> adj[], int u, stack<int> &st, vector<bool> &visited){
        visited[u] = true;
        for(auto v: adj[u]){
            if(visited[v]==false){
                DFSRec(adj, v, st, visited);
            }
        }
        st.push(u);
    }
    
    string topologicalSort(list<int> adj[], int V){
        stack<int> st;
        vector<bool> visited(V, false);
        for(int v=0; v < V; v++){
            if(visited[v]==false){
                DFSRec(adj,v,st,visited);
            }
        }
        string res;
        while(st.empty() == false){
            res += st.top() + 'a';
            st.pop();
        }
        return res;
    }
    
    string findOrder(string words[], int N, int K) {
        list<int> adj[K];
        for(int i=0;i<N-1;i++){
            string word1=words[i];
            string word2=words[i+1];
            for(int j=0;j<min(word1.size(),word2.size());j++){
                if(word1[j]!=word2[j]){
                    int index1=word1[j]-'a';
                    int index2=word2[j]-'a';
                    adj[index1].push_back(index2);
                    break;
                }
            }
        }
        return topologicalSort(adj, K);
}
0
patildhiren443 weeks ago
JAVA - 1.4
ArrayList<ArrayList<Integer>> adj = new ArrayList<>();

     void addEdge(int src, int tar) {
        adj.get(src).add(tar);
    }

     void topo(int src, ArrayList<ArrayList<Integer>> adj, boolean[] visit, Stack<Integer> st) {
        visit[src] = true;

        for (int it : adj.get(src)) {
            if (!visit[it]) {
                topo(it, adj, visit, st);
            }
        }
        st.push(src);
    }

    
    public String findOrder(String [] dic, int n, int k){
        
         for (int i = 0; i < k; i++) {
             adj.add(new ArrayList<>());
         }
        
        for (int i = 0; i < n - 1; i++) {
            String s1 = dic[i];
            String s2 = dic[i + 1];

            for (int j = 0; j < Math.min(s1.length(), s2.length()); j++) {
                if (s1.charAt(j) != s2.charAt(j)) {
                    addEdge(s1.charAt(j) - 'a', s2.charAt(j) - 'a');
                    break;
                }
            }
        }

        boolean[] visit = new boolean[k];
        Stack<Integer> st = new Stack<>();

        for (int i = 0; i < k; i++) {
            if (!visit[i]) {
                topo(i, adj, visit, st);
            }
        }
        
        String s="";
        while(!st.isEmpty()){
            int temp = st.pop()+'a';
            s += (char)temp;
        }
        // System.out.println(s);
        return s;
    }
+1
bhaskarmaheshwari83 weeks ago
class Graph{   int V;   vector<int> *adj;   public:   Graph(int V)   {       this->V=V;       adj=new vector<int>[V];   }   void addEdge(int u,int v)   {       adj[u].push_back(v);   }      void dfs(int src,vector<int>&vis,stack<int> &s)   {       vis[src]=1;       for(auto itr:adj[src])       {           if(!vis[itr])           {               dfs(itr,vis,s);           }       }       s.push(src);   }};class Solution{   public:   string findOrder(string dict[], int n, int K) {       //code here           Graph g(K);                            for(int i=0;i<n-1;i++)       {           string str1=dict[i];           string str2=dict[i+1];           for(int j=0,k=0;j<str1.size()&&k<str2.size();j++,k++)           {            if(str1[j]==str2[k])            continue;            else{                               g.addEdge(str1[j]-'a',str2[k]-'a');                                                                                break;            }           }           }              vector<int> vis(K,0);       stack<int> s;                for (int i = 0; i < K; i++)       if (!vis[i])        g.dfs(i,vis,s);       string str="";       while(!s.empty())       {           str+=s.top()+'a';           s.pop();       }              // return str;     //  cout<<str;       return str;   }
0
milindprajapatmst193 weeks ago
0.3/1.8
 
class Solution{
    public:
    int cnt[26];
    queue<int> q;
    vector<int> edges[26];
    string findOrder(string dict[], int n, int k) {
        memset(cnt, 0, sizeof(cnt));
        for (int i = 1; i < n; i++) {
            int k1 = 0, k2 = 0;
            while (k1 < dict[i - 1].length() && k2 < dict[i].length()) {
                if (dict[i - 1][k1] != dict[i][k2]) {
                    k1 = dict[i - 1][k1] - 'a';
                    k2 = dict[i][k2] - 'a';
                    cnt[k2]++;
                    edges[k1].push_back(k2);
                    break;
                }
                k1++; k2++;
            }
        }
        for (int u = 0; u < k; u++) {
            if (cnt[u] == 0)
                q.push(u);
        }
        string result = "";
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            for (int v : edges[u]) {
                cnt[v]--;
                if (cnt[v] == 0)
                    q.push(v);
            }
            char ch = u + 'a';
            result += ch;
        }
        return result;
    }
};
We strongly recommend solving this problem on your own before viewing its editorial. Do you still
                    want to view the editorial?
 Login to access your submissions. 

Problem


Contest

Reset the IDE using the second button on the top right corner.
Avoid using static/global variables in your code as your code is tested against multiple test cases and these tend to retain their previous values.
Passing the Sample/Custom Test cases does not guarantee the correctness of code. On submission, your code is tested against multiple test cases consisting of all possible corner cases and stress constraints.
You can access the hints to get an idea about what is expected of you as well as the final solution code.
You can view the solutions submitted by other users from the submission tab.