Circle of strings | Practice | GeeksforGeeks

Given an array of lowercase strings A[] of size N, determine if the strings can be chained together to form a circle.
A string X can be chained together with another string Y if the last character of X is same as first
character of Y. If every string of the array can be chained, it will form a circle.
For example, for the array arr[] = {"for", "geek", "rig", "kaf"} the answer will be Yes as the given strings can be chained as "for", "rig", "geek" and "kaf"

Example 1:
Input:
N = 3
A[] = { "abc", "bcd", "cdf" }
Output:
0
Explaination:
These strings can't form a circle 
because no string has 'd'at the starting index.
Example 2:
Input:
N = 4
A[] = { "ab" , "bc", "cd", "da" }
Output:
1
Explaination:
These strings can form a circle 
of strings.

Your Task:
You don't need to read input or print output. Your task is to complete the function isCircle() which takes the length of the array N and the array A as input parameters and returns 1 if we can form a circle or 0 if we cannot.

Expected Time Complexity: O(N)
Expected Auxiliary Space: O(N)

Constraints: 
1 ≤ N ≤ 104
1 ≤ Length of strings ≤ 20
0
himanshujain4572 months ago
Why The Output For The TestCase:
3ceee eeece ddbc
is 0?
can't be it: ddbc→ceee→eeece
+2
kronizerdeltac2 months ago
JAVA SOLUTION: 
class Solution
{
    static boolean dfs(HashMap<Character, ArrayList<Character>> map, HashSet<Character> vis, char ch) {
        if(vis.contains(ch))
            return vis.size() == map.size();
            
        vis.add(ch);
        
        for(char c : map.get(ch)) {
            if(dfs(map, vis, c))
                return true;
        }
        return false;
    }
    static int isCircle(int N, String A[])
    {
        int[] indegree = new int[26], outdegree = new int[26];
        HashMap<Character, ArrayList<Character>> map = new HashMap<>();
        for(String str : A) {
            char first = str.charAt(0), last = str.charAt(str.length() - 1);
            if(!map.containsKey(first))
                map.put(first, new ArrayList<>());
                
            map.get(first).add(last);
            outdegree[first - 'a']++;
            indegree[last - 'a']++;
            
        }
        
        for(int i = 0; i < 26; i++)
            if(indegree[i] != outdegree[i])
                return 0;
                
        HashSet<Character> vis = new HashSet<>();
        return dfs(map, vis, A[0].charAt(0)) ? 1 : 0;
    }
}
0
rajatgarg212cd0162 months ago
// TIME 0.1 USING HASHING ONLY
class Solution{public:int isCircle(int N, vector<string> A){
unordered_map<char,int> m;unordered_map<char,int> m1;//m1 for finding the words which have same letters at the start and endunordered_map<char,int> m2;int n = A.size();for(int i = 0 ; i < n ;i++){m[A[i][0]]++; if(A[i][0] == A[i][A[i].size()-1]){m1[A[i][0]]++;}m2[A[i][A[i].size()-1]]++; }for(int i = 0 ; i < n ;i++){if(m[A[i][0]] != m2[A[i][0]]){ return 0;}if(m[A[i][0]] == m1[A[i][0]]){ // IF THIS EXIST MEANS ALL STRINGS THERE SHOULD HAVE SAME FIRST AND LAST  DIGITS
if(n != m[A[i][0]])return 0;return 1;}}return 1;}};
0
taiphanvan24033 months ago
int deg_in[256];class Solution{   public:   void input(set<char>&s,vector<char>adj[],vector<string>A,int N)   {       for(int i=0;i<N;i++){           s.insert(A[i][0]);           s.insert(A[i].back());           adj[A[i][0]].push_back(A[i].back());           deg_in[A[i].back()]++;       }   }  void dfs(vector<char>adj[],bool visited[],char u){       visited[u]=1;       for(auto i:adj[u])           if(!visited[i]) dfs(adj,visited,i);   }   bool isConnected(vector<char>adj[],bool visited[],set<char>s){       char c;       for(auto i:s)           if(s.size()>0){               c=i;               break;           }       dfs(adj,visited,c);       for(auto i:s)           if(adj[i].size()>0 && !visited[i]) return false;       return true;          }   bool checkEuler(vector<char>adj[],bool visited[],set<char>s)   {       if(!isConnected(adj,visited,s)) return false;       for(auto i:s)           if(deg_in[i]!=adj[i].size()) return false;       return true;   }   int isCircle(int N, vector<string> A)   {       bool visited[256];       memset(visited,0,sizeof(visited));       vector<char>adj[256];       set<char>s;       memset(deg_in,0,sizeof(deg_in));       input(s,adj,A,N);       return checkEuler(adj,visited,s);   }};
+1
shivambhadani1236 months ago
int isCircle(int N, vector<string> A)
    {
        vector<int> adj[26];
        vector<int> in(26, 0);
        vector<int> out(26, 0);
        for(int i=0; i<N; i++) {
            int ch1 = A[i][0]-'a';
            int ch2 = A[i].back()-'a';
            adj[ch1].push_back(ch2);
            out[ch1]++;
            in[ch2]++;
        }
        for(int i=0; i<26; i++) {
            if(in[i]!=out[i]) return 0;
        }
        int src;
        for(int i=0; i<26; i++) {
            if(out[i]) {
                src = i;
                break;
            }
        }
        vector<int> vis(26, 0);
        dfs(adj, vis, src);
        for(int i=0; i<26; i++) {
            if(out[i] && !vis[i]) 
                return 0;
        }
        return 1;
    }
    void dfs(vector<int> adj[], vector<int>& vis, int s) {
        vis[s] = 1;
        for(auto& it: adj[s]) {
            if(!vis[it]) {
                dfs(adj, vis, it);
            }
        }
    }
+2
Abhijit roy7 months ago
Abhijit roy
"HEY, PEOPLE" , this question just tests your knowledge of Euler Concepts of PATHS and CIRCUITS, and the strongly Connected components(KOSARAJU'S or TARJAN'S)...So be sure to check these two concepts before proceeding..
Steps: 1) Making a class graph having member function (addEdge, isConnected, DFS, isEulerian, canBeChained) will be really helpful..It makes tracking through the code easier and if you happen to come and see after a few weeks, the code will be very much understandable.
2) Keep track on inBound Dependency of a node, you can make this in the constructor. Basically this will keep track on the inbound dependencies of a node,Inshort it'll keep track of nodes pointing to it.
3) Use Kosaraju's Algo or Tarjan's algo to find SCC(Strongly Connected Components). If you find some disconnected components return false. Reverse the graph and do the same stuff so we can be sure that the graph has all components connected and all the nodes can be traversed, then return true;
4) Construct the graph using the class and the string of words. Then check if isConnected is false, return false cuz there will be no Eulerian Circuit . Otherwise, return false if the dependency of a node is equal to its list size, which means its not pointing to anyone but itself getting pointed. Its a Euler Concept so be sure to read that first. Now if all shit goes well, we can safely return our bad boy as true
class Graph{private:    int V;    list<int>*adj;    int*in;public:    Graph(int V){        this->V=V;        adj=new list<int>[V];        in=new int[V];        for(int i=0;i<v;i++){ in[i]="0;" }="" }="" void="" addedge(int="" u,int="" v){="" adj[u].push_back(v);="" in[v]++;="" this="" node="" has="" some="" dependecy="" }="" graph="" transpose(){="" graph="" g(v);="" for(int="" i="0;i&lt;V;i++){" for(auto="" it:="" adj[i]){="" g.addedge(it,i);="" }="" }="" return="" g;="" }="" void="" dfs(int="" node,vector<bool=""> &vis){        vis[node]=true;        for(auto it: adj[node]){            if(vis[it]==false){                DFS(it,vis);            }        }    }         bool isConnected(){        vector<bool> vis(V,false);        int i;        for(i=0;i<v;i++){ if(adj[i].size()!="0){" break;="" }="" }="" dfs(i,vis);="" for(int="" i="0;i&lt;V;i++){" if(vis[i]="=false" &&="" adj[i].size()="">0){  //Disconnected Component                return false;            }        }        if(i==V){ //All disconnected components            return false;        }                Graph g=Transpose();                for(int i=0;i<v;i++){ vis[i]="false;" }="" g.dfs(i,vis);="" for(int="" i="0;i&lt;V;i++){" if(vis[i]="=false" &&="" g.adj[i].size()="">0){  //Disconnected Component                return false;            }        }        return true;    }        bool isEulerianCycle(){    if (isConnected() == false){    return false;        }    for (int i = 0; i < V; i++){    if (adj[i].size() != in[i]){    return false;            }       }    return true;    }};class Solution{public:    int isCircle(int n, vector<string> arr) {    Graph g(26);    for (int i = 0; i < n; i++){    string s = arr[i];    g.addEdge(s[0]-'a', s[s.length()-1]-'a');    }    return g.isEulerianCycle();    }};
Link to Google Docs Code: https://docs.google.com/doc...
P.S. GFG please stop messing with code posting...Its a part of learning
+2
hishikeshphukan1237 months ago
class Solution
{
    int graph[26][26];
    void dfs(int v, vector<bool> &visited)
    {
        visited[v] = true;
        for(int i=0 ; i<26 ; i++)
            if(graph[v][i] && !visited[i])
                dfs(i,visited);
    }
    public:
    int isCircle(int N, vector<string> A)
    {
        memset(graph,0,sizeof(graph));
        vector<int> in(26,0);
        vector<int> out(26,0);
        for(int i=0 ; i<N ; i++)
        {
            int a = A[i][0] - 'a';
            int b = A[i].back() - 'a';
            in[a]++;
            out[b]++;
            graph[a][b] = 1;
        }
        for(int i=0 ; i<26 ; i++)
            if(in[i] != out[i])
                return 0;
        vector<bool> visited(26,false);
        int i;
        for(i=0 ; i<26 ; i++)
            if(in[i])
                break;
        dfs(i,visited);
        for(int i=0 ; i<26 ; i++)
            if(in[i] && visited[i] == false)
                return 0;
        return 1;
    }
};
0
Kumar Sahab9 months ago
Kumar Sahab
class Solution{    int graph[26][26];    void dfs(int v, bool visited[])    {        visited[v] = true;        for(int i=0; i<26; i++)            if(graph[v][i] && !visited[i])                dfs(i, visited);    }    public:    int isCircle(int N, vector<string> A)    {        memset(graph, 0, sizeof(graph));        int in[26]={0}, ou[26] = {0};        for(int i=0; i<n; i++)="" {="" int="" a="A[i][0]-'a';" int="" b="A[i].back()-'a';" in[a]++;="" ou[b]++;="" graph[a][b]="1;" }="" for(int="" i="0;" i<26;="" i++)="" if(in[i]!="ou[i])" return="" 0;="" bool="" visited[26]="{false};" int="" i="0;" for(;="" i<26;="" i++)="" if(in[i])="" break;="" dfs(i,="" visited);="" for(int="" i="0;" i<26;="" i++)="" if(in[i]="" &&="" !visited[i])="" return="" 0;="" return="" 1;="" }="" };="" <="" code="">
0
Aviral Ahuja9 months ago
Aviral Ahuja
Test case is failing woth 10000 Strings. can anyone help. Its correct output is 1 and my o/p is 0
static int isCircle(int N, String A[])    {        Map<character,list<character>> map =new HashMap<>();        Map<character,integer> in = new HashMap<>();        Map<character,integer> out = new HashMap<>();        Character start=A[0].charAt(0);        for(String el:A){            Character s=el.charAt(0);            Character e=el.charAt(el.length()-1);            map.putIfAbsent(s,new ArrayList<>());            map.get(s).add(e);            in.merge(s,1,(o,n)->o+n);            out.merge(e,1,(o,n)->o+n);        }        for(Character key : in.keySet()){            if(in.get(key) !=out.get(key)) return 0;        }        Set<character> visited = new HashSet<>();        dfs(map,visited,start);        return (visited.size()==map.size())?1:0;    }    private static void dfs(Map<character,list<character>> map, Set<character> visited, Character start){        visited.add(start);        for(Character ch:map.get(start)){            if(!visited.contains(ch)){                dfs(map,visited,ch);            }        }    }
0
T9 months ago
T
class Solution{    public:    int isCircle(int n, vector<string> v)    {       for (int i=0; i<=n-1; i++)        {            int x=v[i].length();            int y=v[i+1].length();            if (v[i][x-1]==v[i+1][0])            {                continue;            }            else            {                return 0;            }        }        if (v[0][0]==v[n-1][v[n-1].length()-1])        {            return 1;        }        return 0;    }};
what is wrong with this code?
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.