Word Chaining

Find the circular chain in the given list of words.

Statement

Given a list of words, figure out whether the given words can form a circular chain. Assume that a single word can never form a chain.

Two words can be chained together if the first word’s last letter is equal to the second word’s first letter.

Note: Assume that all the words are lower case.

Example

Consider the following words:

These words can form the following chain:

Sample input

Input will be a list of words:

list_words = ["eve", "eat", "ripe", "tear"]

Expected output

true

Try it yourself #

GraphChain.cpp
VertexChain.cpp
#include "VertexChain.cpp"
#include <string>
#include <iostream>
using namespace std;
class graph {
public:
vector<VertexChain*> g;
// Challenge function
bool CanChainWords(int list_size) // Receiving the size of list from main
{
// TODO: Write - Your - Code
return false;
}
// This method creates a graph from a list of words. A node of
// the graph contains a character representing the start or end
// character of a word.
void CreateGraph(vector<string> words_list) {
for (int i = 0; i < words_list.size(); i++) {
string word = words_list[i];
char start_char = word[0];
char end_char = word[word.length() - 1];
VertexChain* start = VertexChainExists(start_char);
if (start == nullptr) {
start = new VertexChain(start_char, false);
g.push_back(start);
}
VertexChain* end = VertexChainExists(end_char);
if (end == nullptr) {
end = new VertexChain(end_char, false);
g.push_back(end);
}
// Add an edge from start vertex to end vertex
AddEdge(start, end);
}
}
// This method returns the VertexChain with a given value if it
// already exists in the graph, returns NULL otherwise
VertexChain* VertexChainExists(char value) {
for (int i = 0; i < this->g.size(); i++) {
if (g[i]->value == value) {
return g[i];
}
}
return nullptr;
}
// This method returns TRUE if all nodes of the graph have
// been visited
bool AllVisited() {
for (int i = 0; i < g.size(); i++) {
if (g[i]->visited == false) {
return false;
}
}
return true;
}
// This method adds an edge from start VertexChain to end VertexChain by
// adding the end VertexChain in the adjacency list of start VertexChain
// It also adds the start VertexChain to the in_vertices of end VertexChain
void AddEdge(VertexChain* start, VertexChain* end) {
start->adj_vertices.push_back(end);
end->in_vertices.push_back(start);
}
// This method returns TRUE if out degree of each vertex is equal
// to its in degree, returns FALSE otherwise
bool OutEqualsIn() {
for (int i = 0; i < g.size(); i++) {
int out = g[i]->adj_vertices.size();
int inn = g[i]->in_vertices.size();
if (out != inn) {
return false;
}
}
return true;
}
void PrintGraph() {
for (int i = 0; i < g.size(); i++) {
cout << g[i] << ' ' << g[i]->visited << endl;
vector<VertexChain*> adj = g[i]->adj_vertices;
for (int j = 0; j < adj.size(); j++) {
cout << adj[j] << ' ';
}
cout << endl;
}
}
};

Solution

Naive solution

A naive solution for this problem is to find all the permutations of these strings recursively and return true once a chain is detected. The run time for this approach is O(n!).

Although, practically, it is faster as we prune permutations early if they do not conform to our chaining logic.

Optimized solution

A better solution is to do a linear pass of the word list and construct a graph that represents the start and end characters of each word. We need to add an edge from the starting character of a word to its ending character for each word in the list. If there ...

Access this course and 1400+ top-rated courses and projects.