{"id":2070,"date":"2024-02-01T13:00:00","date_gmt":"2024-02-01T13:00:00","guid":{"rendered":"https:\/\/favtutor.com\/articles\/?p=2070"},"modified":"2024-03-02T07:52:32","modified_gmt":"2024-03-02T07:52:32","slug":"alien-dictionary-problem","status":"publish","type":"post","link":"https:\/\/favtutor.com\/articles\/alien-dictionary-problem\/","title":{"rendered":"Alien Dictionary Problem (C++, Java, Python)"},"content":{"rendered":"\n<p>The dictionary provides details about the order of alphabetical characters. For example, if abc, abd are two words where abd comes after abc, it means c is smaller than d. But if order is opposite this implies d is smaller than c. In this article, we will learn how to solve the Alien Dictionary problem.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What is the Alien Dictionary Problem?<\/strong><\/h2>\n\n\n\n<p><strong>In the Alien Dictionary problem, we are given an array containing words in the order it was written in a dictionary. This dictionary is not the same as our actual dictionary. You have to find the order of characters in that dictionary. <\/strong><\/p>\n\n\n\n<p>For example, array = [ \u201cacd\u201d, \u201cdc\u201d, \u201cca\u201d]. This means the actual order of letters is a, d, c.\u00a0<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/JTKxxXMmNPrU6gJSx1vOOUp8CvuEd-EoxjwM32lJWaOm7eVPWjWhcH45y2ckRFAY5j2UmvlrkEtH5FvWlTVPsvehajRJ7jHynEzyjbDip3s2x_08hzKZCI3A3-Egt2ria7_sa6Ow8Y4Od7RKhBtGzHY\" alt=\"Example\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/PjwtD9_NhrUYhnkWX3eZuRhmnWTag58Tt-_5seBZsBoU0zUJD3Dn34kX1t-haw8nq0-4JgruOxqaI2qn-emYOOHw3RujgHHGUb2o08on_-xuQwbZCz8HABaEQ42WEdL_CRF5l_p1jAX-BrRLJnkKJ8k\" alt=\"Example\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Topological Sorting Approach<\/strong><\/h2>\n\n\n\n<p>In <a href=\"https:\/\/favtutor.com\/blogs\/topological-sort-python\">topological sorting<\/a>, we find out the order of the nodes. As in this case, we have to find out the order of the characters so we will assume characters a individual nodes, and the edges represent the relative order between them. <\/p>\n\n\n\n<p><strong>We will first construct the graph by assuming each letter is an individual character and then construct the directed edges which denotes the direction in which we are moving. <\/strong>If we find out that the graph contains a cycle then topological sorting is not possible if not then return the ans.<\/p>\n\n\n\n<p>Let\u2019s understand this approach step by step:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>First, create an adjacency list that stores the total number of unique characters in the array.<\/li>\n\n\n\n<li>Now create the edges by comparing the characters of the adjacent words. Create the edges between the first characters which does not match.<\/li>\n\n\n\n<li>Now find if the graph contains a cycle or not. If it contains cycle return the order is not possible to find.<\/li>\n\n\n\n<li>If not find the topological order of the given graph and return the order.<\/li>\n<\/ol>\n\n\n\n<p>Let\u2019s examine the code for the above process.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>C++ Code<\/strong><\/h3>\n\n\n\n<p>Here is how to implement topological sorting to solve Alien Dictionary problem:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-c++src&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;C++&quot;,&quot;modeName&quot;:&quot;cpp&quot;}\">#include&lt;bits\/stdc++.h&gt;\nusing namespace std;\n\nvector&lt;int&gt;cunt(26,0);\n\nvoid add_edge(vector&lt;vector&lt;int&gt;&gt;&amp;list, char a, char b){\n    list[a-'a'].push_back(b-'a');\n}\n\nvoid dfs(vector&lt;vector&lt;int&gt;&gt;&amp; list, vector&lt;int&gt;&amp; temp, int curr, bool&amp; flag)\n{\n\n\ttemp[curr] = 1;\n\n\tfor (int i = 0; i &lt; list[curr].size(); i++) {\n\t\tint j = list[curr][i];\n\t\tif (temp[j] == 1) {\n\t\t\tflag = true;\n\t\t\treturn;\n\t\t}\n\t\telse if (temp[j] == 0) {\n\t\t\tdfs(list, temp, j, flag);\n\t\t}\n\t}\n\n\ttemp[curr] = 2;\n\treturn ;\n}\n\n\nbool is_cycle(vector&lt;vector&lt;int&gt;&gt;&amp; list, vector&lt;int&gt;temp){\n    \n    bool flag = false;\n    \n    for(int i=0; i&lt;26; i++){\n        if(list[i].size()){\n            if(temp[i] == 0) dfs(list, temp, i, flag);\n        }\n    }\n    \n    return flag;\n}\n\nvoid topological_sort_fun(vector&lt;vector&lt;int&gt;&gt;&amp;list, int curr, vector&lt;bool&gt;&amp; visited, stack&lt;char&gt;&amp; st)\n{\n\tvisited[curr] = true;\n\t\n\tfor (int i = 0; i &lt; list[curr].size(); i++) {\n\t\tint x = list[curr][i];\n\t\tif (visited[x] == false) {\n\t\t\ttopological_sort_fun(list, x, visited, st);\n\t\t}\n\t}\n\tst.push('a' + curr);\n\treturn;\n}\n\nstack&lt;char&gt; topological_sort(vector&lt;vector&lt;int&gt;&gt;&amp; list){\n    \n    vector&lt;bool&gt;visited(26,false);\n    stack&lt;char&gt;st;\n    \n    for(int i=0;i&lt;26;i++){\n        if(visited[i]==false &amp;&amp; cunt[i]&gt;0){\n            topological_sort_fun(list, i, visited, st);\n        }\n    }\n    \n    return st;\n    \n}\n\nvector&lt;char&gt; find_order(vector&lt;string&gt;&amp; arr){\n    \/\/ first we find out how many unique characters are there\n    \n    for(int i=0;i&lt;arr.size();i++){\n        for(int j=0;j&lt;arr[i].size();j++){\n            cunt[arr[i][j]-'a']++;\n        }\n    }\n\n    \n    \/\/ finding the edges by looking at adjacent elements \n    \n    int n = arr.size();\n    vector&lt;vector&lt;int&gt;&gt;list(26);\n    for (int i = 0; i &lt; n - 1; i++) {\n\t\n\t\tint j = 0;\n\t\tint sz_1 = arr[i].size();\n\t\tint sz_2 = arr[i+1].size();\n\t\t\n\t\twhile (j &lt; sz_1 &amp;&amp; j &lt; sz_2) {  \n\t\t\tif (arr[i][j] != arr[i+1][j]) { \n\t\t\t\tadd_edge(list, arr[i][j], arr[i+1][j]);\t\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tj++;\n\t\t}\n\t}\n    \n    vector&lt;int&gt;temp(26, 0);\n    \n    \/\/ if graph consist of cycle or not\n    \n    if(is_cycle(list, temp)){\n        cout&lt;&lt;&quot;No valid order is possible&quot;;\n        return {};\n    }\n    \n    \/\/ find the topologicalSort\n    stack&lt;char&gt;st = topological_sort(list);\n    \n    vector&lt;char&gt;res;\n    \n    while(st.size()){\n        char ch = st.top();\n        res.push_back(ch);\n        st.pop();\n    }\n\n    return res;\n}\n\nint main(){\n    vector&lt;string&gt;arr = {&quot;bcd&quot;, &quot;ddc&quot;, &quot;dcb&quot;, &quot;ab&quot;};\n    vector&lt;char&gt;v = find_order(arr);\n    \n    for(int i=0;i&lt;v.size();i++){\n        cout&lt;&lt;v[i]&lt;&lt;&quot; &quot;;\n    }\n    cout&lt;&lt;endl;\n    \n    return 0;\n}<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Java Code<\/strong><\/h3>\n\n\n\n<p>Here is the Java program to do the same:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Java&quot;,&quot;modeName&quot;:&quot;java&quot;}\">import java.util.*;\n\npublic class Main {\n    static int[] count = new int[26];\n\n    static void addEdge(ArrayList&lt;ArrayList&lt;Integer&gt;&gt; list, char a, char b) {\n        list.get(a - 'a').add(b - 'a');\n    }\n\n    static void dfs(ArrayList&lt;ArrayList&lt;Integer&gt;&gt; list, int[] temp, int curr, boolean[] flag) {\n        temp[curr] = 1;\n\n        for (int i = 0; i &lt; list.get(curr).size(); i++) {\n            int j = list.get(curr).get(i);\n            if (temp[j] == 1) {\n                flag[0] = true;\n                return;\n            } else if (temp[j] == 0) {\n                dfs(list, temp, j, flag);\n            }\n        }\n\n        temp[curr] = 2;\n    }\n\n    static boolean isCycle(ArrayList&lt;ArrayList&lt;Integer&gt;&gt; list, int[] temp) {\n        boolean[] flag = {false};\n\n        for (int i = 0; i &lt; 26; i++) {\n            if (!list.get(i).isEmpty() &amp;&amp; temp[i] == 0) {\n                dfs(list, temp, i, flag);\n            }\n        }\n\n        return flag[0];\n    }\n\n    static void topologicalSortFun(ArrayList&lt;ArrayList&lt;Integer&gt;&gt; list, int curr, boolean[] visited, Stack&lt;Character&gt; st) {\n        visited[curr] = true;\n\n        for (int i = 0; i &lt; list.get(curr).size(); i++) {\n            int x = list.get(curr).get(i);\n            if (!visited[x]) {\n                topologicalSortFun(list, x, visited, st);\n            }\n        }\n        st.push((char)('a' + curr));\n    }\n\n    static Stack&lt;Character&gt; topologicalSort(ArrayList&lt;ArrayList&lt;Integer&gt;&gt; list) {\n        boolean[] visited = new boolean[26];\n        Stack&lt;Character&gt; st = new Stack&lt;&gt;();\n\n        for (int i = 0; i &lt; 26; i++) {\n            if (!visited[i] &amp;&amp; count[i] &gt; 0) {\n                topologicalSortFun(list, i, visited, st);\n            }\n        }\n\n        return st;\n    }\n\n    static ArrayList&lt;Character&gt; findOrder(ArrayList&lt;String&gt; arr) {\n        for (String s : arr) {\n            for (char c : s.toCharArray()) {\n                count[c - 'a']++;\n            }\n        }\n\n        int n = arr.size();\n        ArrayList&lt;ArrayList&lt;Integer&gt;&gt; list = new ArrayList&lt;&gt;();\n        for (int i = 0; i &lt; 26; i++) {\n            list.add(new ArrayList&lt;&gt;());\n        }\n\n        for (int i = 0; i &lt; n - 1; i++) {\n            int j = 0;\n            int sz_1 = arr.get(i).length();\n            int sz_2 = arr.get(i + 1).length();\n            while (j &lt; sz_1 &amp;&amp; j &lt; sz_2) {\n                if (arr.get(i).charAt(j) != arr.get(i + 1).charAt(j)) {\n                    addEdge(list, arr.get(i).charAt(j), arr.get(i + 1).charAt(j));\n                    break;\n                }\n                j++;\n            }\n        }\n\n        int[] temp = new int[26];\n        if (isCycle(list, temp)) {\n            System.out.println(&quot;No valid order is possible&quot;);\n            return new ArrayList&lt;&gt;();\n        }\n\n        Stack&lt;Character&gt; st = topologicalSort(list);\n        ArrayList&lt;Character&gt; res = new ArrayList&lt;&gt;();\n\n        while (!st.isEmpty()) {\n            char ch = st.pop();\n            res.add(ch);\n        }\n\n        return res;\n    }\n\n    public static void main(String[] args) {\n        ArrayList&lt;String&gt; arr = new ArrayList&lt;&gt;(Arrays.asList(&quot;bcd&quot;, &quot;ddc&quot;, &quot;dcb&quot;, &quot;ab&quot;));\n        ArrayList&lt;Character&gt; v = findOrder(arr);\n\n        for (char c : v) {\n            System.out.print(c + &quot; &quot;);\n        }\n        System.out.println();\n    }\n}<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Python Code<\/strong><\/h3>\n\n\n\n<p>Python can also be used to solve this leetcode problem:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text\/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}\">count = [0] * 26\n\ndef add_edge(list, a, b):\n    list[ord(a) - ord('a')].append(ord(b) - ord('a'))\n\ndef dfs(list, temp, curr, flag):\n    temp[curr] = 1\n\n    for i in range(len(list[curr])):\n        j = list[curr][i]\n        if temp[j] == 1:\n            flag[0] = True\n            return\n        elif temp[j] == 0:\n            dfs(list, temp, j, flag)\n\n    temp[curr] = 2\n\ndef is_cycle(list, temp):\n    flag = [False]\n\n    for i in range(26):\n        if list[i] and temp[i] == 0:\n            dfs(list, temp, i, flag)\n\n    return flag[0]\n\ndef topological_sort_fun(list, curr, visited, st):\n    visited[curr] = True\n\n    for i in range(len(list[curr])):\n        x = list[curr][i]\n        if not visited[x]:\n            topological_sort_fun(list, x, visited, st)\n    st.append(chr(ord('a') + curr))\n\ndef topological_sort(list):\n    visited = [False] * 26\n    st = []\n\n    for i in range(26):\n        if not visited[i] and count[i] &gt; 0:\n            topological_sort_fun(list, i, visited, st)\n\n    return st\n\ndef find_order(arr):\n    global count\n    for s in arr:\n        for c in s:\n            count[ord(c) - ord('a')] += 1\n\n    n = len(arr)\n    list = [[] for _ in range(26)]\n\n    for i in range(n - 1):\n        j = 0\n        sz_1 = len(arr[i])\n        sz_2 = len(arr[i + 1])\n        while j &lt; sz_1 and j &lt; sz_2:\n            if arr[i][j] != arr[i + 1][j]:\n                add_edge(list, arr[i][j], arr[i + 1][j])\n                break\n            j += 1\n\n    temp = [0] * 26\n    if is_cycle(list, temp):\n        print(&quot;No valid order is possible&quot;)\n        return []\n\n    st = topological_sort(list)\n    res = []\n\n    while st:\n        ch = st.pop()\n        res.append(ch)\n\n    return res\n\nif __name__ == &quot;__main__&quot;:\n    arr = [&quot;bcd&quot;, &quot;ddc&quot;, &quot;dcb&quot;, &quot;ab&quot;]\n    v = find_order(arr)\n\n    for c in v:\n        print(c, end=&quot; &quot;)\n    print()<\/pre><\/div>\n\n\n\n<p><strong>Output:&nbsp;<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code has-black-color has-text-color has-background has-link-color wp-elements-dd7bca8cdf712dd37a7d3eea1d96b876\" style=\"background-color:#fedcba\"><code>b d c a&nbsp;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Complexity Analysis<\/strong><\/h3>\n\n\n\n<p><strong>The time complexity for implementing topological sorting to solve the Alien Dictionary problem is O(n + k), where n is the total number of words in the array and k is the total unique characters in the array. <\/strong>As we are making an adjacency list having a node equal to k. <\/p>\n\n\n\n<p>The space complexity for the above code is <strong>O(n + k).<\/strong> As there are total n different words and we are comparing each adjacent word and based on this we will push that character into one of the nodes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n\n\n\n<p>This article helps us to understand the topological sort in more depth to verify an Alien Dictionary. We find out how we can apply topological sort when we have to find the order of nodes in the graph. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Understand what is the Alien Dictionary Problem and how to solve it using the Topological Sort approach.<\/p>\n","protected":false},"author":14,"featured_media":2072,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jnews-multi-image_gallery":[],"jnews_single_post":null,"jnews_primary_category":{"id":"","hide":""},"footnotes":""},"categories":[7],"tags":[14,15],"class_list":["post-2070","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-data-structures-algorithms","tag-dsa","tag-leetcode"],"_links":{"self":[{"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/posts\/2070","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/users\/14"}],"replies":[{"embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/comments?post=2070"}],"version-history":[{"count":3,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/posts\/2070\/revisions"}],"predecessor-version":[{"id":2120,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/posts\/2070\/revisions\/2120"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/media\/2072"}],"wp:attachment":[{"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/media?parent=2070"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/categories?post=2070"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/tags?post=2070"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}