Articles by FavTutor
  • AI News
  • Data Structures
  • Web Developement
  • AI Code GeneratorNEW
  • Student Help
  • Main Website
No Result
View All Result
FavTutor
  • AI News
  • Data Structures
  • Web Developement
  • AI Code GeneratorNEW
  • Student Help
  • Main Website
No Result
View All Result
Articles by FavTutor
No Result
View All Result
Home Data Structures and Algorithms

Alien Dictionary Problem (C++, Java, Python)

Mansi Agarwal by Mansi Agarwal
March 2, 2024
Reading Time: 8 mins read
Alien Dictionary Problem
Follow us on Google News   Subscribe to our newsletter

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.

What is the Alien Dictionary Problem?

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.

For example, array = [ “acd”, “dc”, “ca”]. This means the actual order of letters is a, d, c. 

Example
Example

Topological Sorting Approach

In topological sorting, 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.

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. If we find out that the graph contains a cycle then topological sorting is not possible if not then return the ans.

Let’s understand this approach step by step:

  1. First, create an adjacency list that stores the total number of unique characters in the array.
  2. Now create the edges by comparing the characters of the adjacent words. Create the edges between the first characters which does not match.
  3. Now find if the graph contains a cycle or not. If it contains cycle return the order is not possible to find.
  4. If not find the topological order of the given graph and return the order.

Let’s examine the code for the above process.

C++ Code

Here is how to implement topological sorting to solve Alien Dictionary problem:

#include<bits/stdc++.h>
using namespace std;

vector<int>cunt(26,0);

void add_edge(vector<vector<int>>&list, char a, char b){
    list[a-'a'].push_back(b-'a');
}

void dfs(vector<vector<int>>& list, vector<int>& temp, int curr, bool& flag)
{

	temp[curr] = 1;

	for (int i = 0; i < list[curr].size(); i++) {
		int j = list[curr][i];
		if (temp[j] == 1) {
			flag = true;
			return;
		}
		else if (temp[j] == 0) {
			dfs(list, temp, j, flag);
		}
	}

	temp[curr] = 2;
	return ;
}


bool is_cycle(vector<vector<int>>& list, vector<int>temp){
    
    bool flag = false;
    
    for(int i=0; i<26; i++){
        if(list[i].size()){
            if(temp[i] == 0) dfs(list, temp, i, flag);
        }
    }
    
    return flag;
}

void topological_sort_fun(vector<vector<int>>&list, int curr, vector<bool>& visited, stack<char>& st)
{
	visited[curr] = true;
	
	for (int i = 0; i < list[curr].size(); i++) {
		int x = list[curr][i];
		if (visited[x] == false) {
			topological_sort_fun(list, x, visited, st);
		}
	}
	st.push('a' + curr);
	return;
}

stack<char> topological_sort(vector<vector<int>>& list){
    
    vector<bool>visited(26,false);
    stack<char>st;
    
    for(int i=0;i<26;i++){
        if(visited[i]==false && cunt[i]>0){
            topological_sort_fun(list, i, visited, st);
        }
    }
    
    return st;
    
}

vector<char> find_order(vector<string>& arr){
    // first we find out how many unique characters are there
    
    for(int i=0;i<arr.size();i++){
        for(int j=0;j<arr[i].size();j++){
            cunt[arr[i][j]-'a']++;
        }
    }

    
    // finding the edges by looking at adjacent elements 
    
    int n = arr.size();
    vector<vector<int>>list(26);
    for (int i = 0; i < n - 1; i++) {
	
		int j = 0;
		int sz_1 = arr[i].size();
		int sz_2 = arr[i+1].size();
		
		while (j < sz_1 && j < sz_2) {  
			if (arr[i][j] != arr[i+1][j]) { 
				add_edge(list, arr[i][j], arr[i+1][j]);	
				break;
			}
			j++;
		}
	}
    
    vector<int>temp(26, 0);
    
    // if graph consist of cycle or not
    
    if(is_cycle(list, temp)){
        cout<<"No valid order is possible";
        return {};
    }
    
    // find the topologicalSort
    stack<char>st = topological_sort(list);
    
    vector<char>res;
    
    while(st.size()){
        char ch = st.top();
        res.push_back(ch);
        st.pop();
    }

    return res;
}

int main(){
    vector<string>arr = {"bcd", "ddc", "dcb", "ab"};
    vector<char>v = find_order(arr);
    
    for(int i=0;i<v.size();i++){
        cout<<v[i]<<" ";
    }
    cout<<endl;
    
    return 0;
}

Java Code

Here is the Java program to do the same:

import java.util.*;

public class Main {
    static int[] count = new int[26];

    static void addEdge(ArrayList<ArrayList<Integer>> list, char a, char b) {
        list.get(a - 'a').add(b - 'a');
    }

    static void dfs(ArrayList<ArrayList<Integer>> list, int[] temp, int curr, boolean[] flag) {
        temp[curr] = 1;

        for (int i = 0; i < list.get(curr).size(); i++) {
            int j = list.get(curr).get(i);
            if (temp[j] == 1) {
                flag[0] = true;
                return;
            } else if (temp[j] == 0) {
                dfs(list, temp, j, flag);
            }
        }

        temp[curr] = 2;
    }

    static boolean isCycle(ArrayList<ArrayList<Integer>> list, int[] temp) {
        boolean[] flag = {false};

        for (int i = 0; i < 26; i++) {
            if (!list.get(i).isEmpty() && temp[i] == 0) {
                dfs(list, temp, i, flag);
            }
        }

        return flag[0];
    }

    static void topologicalSortFun(ArrayList<ArrayList<Integer>> list, int curr, boolean[] visited, Stack<Character> st) {
        visited[curr] = true;

        for (int i = 0; i < list.get(curr).size(); i++) {
            int x = list.get(curr).get(i);
            if (!visited[x]) {
                topologicalSortFun(list, x, visited, st);
            }
        }
        st.push((char)('a' + curr));
    }

    static Stack<Character> topologicalSort(ArrayList<ArrayList<Integer>> list) {
        boolean[] visited = new boolean[26];
        Stack<Character> st = new Stack<>();

        for (int i = 0; i < 26; i++) {
            if (!visited[i] && count[i] > 0) {
                topologicalSortFun(list, i, visited, st);
            }
        }

        return st;
    }

    static ArrayList<Character> findOrder(ArrayList<String> arr) {
        for (String s : arr) {
            for (char c : s.toCharArray()) {
                count[c - 'a']++;
            }
        }

        int n = arr.size();
        ArrayList<ArrayList<Integer>> list = new ArrayList<>();
        for (int i = 0; i < 26; i++) {
            list.add(new ArrayList<>());
        }

        for (int i = 0; i < n - 1; i++) {
            int j = 0;
            int sz_1 = arr.get(i).length();
            int sz_2 = arr.get(i + 1).length();
            while (j < sz_1 && j < sz_2) {
                if (arr.get(i).charAt(j) != arr.get(i + 1).charAt(j)) {
                    addEdge(list, arr.get(i).charAt(j), arr.get(i + 1).charAt(j));
                    break;
                }
                j++;
            }
        }

        int[] temp = new int[26];
        if (isCycle(list, temp)) {
            System.out.println("No valid order is possible");
            return new ArrayList<>();
        }

        Stack<Character> st = topologicalSort(list);
        ArrayList<Character> res = new ArrayList<>();

        while (!st.isEmpty()) {
            char ch = st.pop();
            res.add(ch);
        }

        return res;
    }

    public static void main(String[] args) {
        ArrayList<String> arr = new ArrayList<>(Arrays.asList("bcd", "ddc", "dcb", "ab"));
        ArrayList<Character> v = findOrder(arr);

        for (char c : v) {
            System.out.print(c + " ");
        }
        System.out.println();
    }
}

Python Code

Python can also be used to solve this leetcode problem:

count = [0] * 26

def add_edge(list, a, b):
    list[ord(a) - ord('a')].append(ord(b) - ord('a'))

def dfs(list, temp, curr, flag):
    temp[curr] = 1

    for i in range(len(list[curr])):
        j = list[curr][i]
        if temp[j] == 1:
            flag[0] = True
            return
        elif temp[j] == 0:
            dfs(list, temp, j, flag)

    temp[curr] = 2

def is_cycle(list, temp):
    flag = [False]

    for i in range(26):
        if list[i] and temp[i] == 0:
            dfs(list, temp, i, flag)

    return flag[0]

def topological_sort_fun(list, curr, visited, st):
    visited[curr] = True

    for i in range(len(list[curr])):
        x = list[curr][i]
        if not visited[x]:
            topological_sort_fun(list, x, visited, st)
    st.append(chr(ord('a') + curr))

def topological_sort(list):
    visited = [False] * 26
    st = []

    for i in range(26):
        if not visited[i] and count[i] > 0:
            topological_sort_fun(list, i, visited, st)

    return st

def find_order(arr):
    global count
    for s in arr:
        for c in s:
            count[ord(c) - ord('a')] += 1

    n = len(arr)
    list = [[] for _ in range(26)]

    for i in range(n - 1):
        j = 0
        sz_1 = len(arr[i])
        sz_2 = len(arr[i + 1])
        while j < sz_1 and j < sz_2:
            if arr[i][j] != arr[i + 1][j]:
                add_edge(list, arr[i][j], arr[i + 1][j])
                break
            j += 1

    temp = [0] * 26
    if is_cycle(list, temp):
        print("No valid order is possible")
        return []

    st = topological_sort(list)
    res = []

    while st:
        ch = st.pop()
        res.append(ch)

    return res

if __name__ == "__main__":
    arr = ["bcd", "ddc", "dcb", "ab"]
    v = find_order(arr)

    for c in v:
        print(c, end=" ")
    print()

Output: 

b d c a 

Complexity Analysis

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. As we are making an adjacency list having a node equal to k.

The space complexity for the above code is O(n + k). 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.

Conclusion

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.

ShareTweetShareSendSend
Mansi Agarwal

Mansi Agarwal

I am Mansi Agarwal, a final-year student at IIT BHU. I am very keen on competitive programming, with my primary area of interest being Data Structures & Algorithms. I have solved over 1000 LeetCode problems.

RelatedPosts

validate ip address

Validate IP Address Problem ( C++, JAVA, Python)

April 3, 2025
Shortest Palindrome Problem

Shortest Palindrome Problem ( C++, JAVA, Python)

April 4, 2025
Zigzag Conversion Problem

Zigzag Conversion Problem (C++, Java, Python)

April 4, 2025
Next Right Pointers In Each Node

Populating Next Right Pointers In Each Node (with code)

March 27, 2024
Coin Change II

Coin Change II Problem (C++, Java, Python)

April 7, 2025

About FavTutor

FavTutor is a trusted online tutoring service to connects students with expert tutors to provide guidance on Computer Science subjects like Java, Python, C, C++, SQL, Data Science, Statistics, etc.

Categories

  • AI News, Research & Latest Updates
  • Trending
  • Data Structures
  • Web Developement
  • Data Science

Important Subjects

  • Python Assignment Help
  • C++ Help
  • R Programming Help
  • Java Homework Help
  • Programming Help

Resources

  • About Us
  • Contact Us
  • Editorial Policy
  • Privacy Policy
  • Terms and Conditions

Website listed on Ecomswap. © Copyright 2025 All Rights Reserved.

No Result
View All Result
  • AI News
  • Data Structures
  • Web Developement
  • AI Code Generator
  • Student Help
  • Main Website

Website listed on Ecomswap. © Copyright 2025 All Rights Reserved.