Suppose we have a list of words. We have to check the given words can be chained to form a circle. A word A can be placed in front of another word B in a chained circle if only the last character of A is identical to the first character of B. Every word has to be used and can be used only once (the first/last word will not be considered).
So, if the input is like words = ["ant","dog","tamarind","nausea","gun"], then the output will be True.
To solve this, we will follow these steps −
graph := a new key-value pair list
seen := a new set
inDegree := a new key-value pair list
outDegree := a new key-value pair list
for each word in words, do
start := word[0]
end := word[-1]
insert end at the end of graph[start]
outDegree[start] := outDegree[start] + 1
inDegree[end] := inDegree[end] + 1
for each node in outDegree, do
if outDegree[node] is not same as inDegree[node], then
return False
dfs(words[0,0])
return size of seen if it is same as size of graph
Define a function dfs() . This will take node.
add(node) in seen
for each child in graph[node], do
if child is not present in seen, then
dfs(child)
Example
Let us see the following implementation to get better understanding −
import collections class Solution: def solve(self, words): self.graph = collections.defaultdict(list) self.seen = set() inDegree = collections.Counter() outDegree = collections.Counter() for word in words: start = word[0] end = word[-1] self.graph[start].append(end) outDegree[start] += 1 inDegree[end] += 1 for node in outDegree: if outDegree[node] != inDegree[node]: return False self.dfs(words[0][0]) return len(self.seen) == len(self.graph) def dfs(self, node): self.seen.add(node) for child in self.graph[node]: if child not in self.seen: self.dfs(child) ob = Solution() print(ob.solve(["ant","dog","tamarind","nausea","gun"]))
Input
["ant","dog","tamarind","nausea","gun"]
Output
True