Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to Find Out if There is a Short Circuit in Input Words in Python
Given a list of words, we need to check if they can be chained to form a circle. A word A can be placed before word B if the last character of A matches the first character of B. Each word must be used exactly once.
For example, with words = ["ant", "dog", "tamarind", "nausea", "gun"], we can form: ant ? tamarind ? dog ? gun ? nausea ? ant (circle completed).
Algorithm
This problem is solved using graph theory concepts ?
Build a directed graph where each character is a node
Add edges from first character to last character of each word
Check if in-degree equals out-degree for all nodes (necessary for Eulerian circuit)
Verify the graph is strongly connected using DFS
Implementation
import collections
class Solution:
def solve(self, words):
self.graph = collections.defaultdict(list)
self.seen = set()
inDegree = collections.Counter()
outDegree = collections.Counter()
# Build the graph
for word in words:
start = word[0]
end = word[-1]
self.graph[start].append(end)
outDegree[start] += 1
inDegree[end] += 1
# Check if in-degree equals out-degree for all nodes
for node in outDegree:
if outDegree[node] != inDegree[node]:
return False
# Check if graph is strongly connected
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)
# Test the solution
ob = Solution()
words = ["ant", "dog", "tamarind", "nausea", "gun"]
result = ob.solve(words)
print(f"Can form circle: {result}")
Can form circle: True
How It Works
Let's trace through the example ?
words = ["ant", "dog", "tamarind", "nausea", "gun"] # Graph edges created: # a ? t (from "ant") # d ? g (from "dog") # t ? d (from "tamarind") # n ? a (from "nausea") # g ? n (from "gun") # This forms: a ? t ? d ? g ? n ? a (complete circle)
Alternative Approach
Here's a more concise implementation ?
from collections import defaultdict, Counter
def can_form_circle(words):
if not words:
return False
graph = defaultdict(list)
in_degree = Counter()
out_degree = Counter()
# Build graph and count degrees
for word in words:
first, last = word[0], word[-1]
graph[first].append(last)
out_degree[first] += 1
in_degree[last] += 1
# Check degree condition
if any(in_degree[node] != out_degree[node] for node in out_degree):
return False
# Check connectivity with DFS
visited = set()
def dfs(node):
visited.add(node)
for neighbor in graph[node]:
if neighbor not in visited:
dfs(neighbor)
dfs(words[0][0])
return len(visited) == len(graph)
# Test cases
test_cases = [
["ant", "dog", "tamarind", "nausea", "gun"],
["hello", "world"],
["cat", "dog", "god", "tree", "eat"]
]
for i, words in enumerate(test_cases, 1):
result = can_form_circle(words)
print(f"Test case {i}: {result}")
Test case 1: True Test case 2: False Test case 3: True
Key Points
Time Complexity: O(N) where N is the total number of characters
Space Complexity: O(1) for the graph (at most 26 characters)
Eulerian Circuit: A directed graph has an Eulerian circuit if in-degree equals out-degree for all vertices and the graph is strongly connected
Conclusion
This problem uses graph theory to check if words can form a circular chain. We build a directed graph and verify both degree conditions and connectivity using DFS traversal.
