Interview Question
Country: United States
@rganeyev
e.g. because Floyd-Warshall doesn't work with negative cycles as bellmann ford doesn't
an intuitive prove of this is that if you walk through the negative cycle once more, you will get an even "longer" path with the words of the question or a even "shorter path" in terms of the original algorithms.
Further, it has been shown that the problem can be deduced to a known NP complete problem.
but anyway, I don't agree it's a useless exercise, sometimes even an exponential algo is okay as long as you know it is exponential and if you can roughly prove it's in NP in an interview, I suppose some companies would love you ;-)
def findLongestCycle(root):
longest_cycle = []
dfs_stack = [root]
cycle_stack = [root]
while (dfs_stack):
# DFS
node = dfs_stack.pop()
node.visited = True
# This boolean checks whether a node's neighbors have been fully explored
found_unvisited = False
for neighbor in node.neighbors:
if (!neighbor.visited):
# Add node to our stacks to explore
dfs_stack.append(neighbor)
cycle_stack.append(neighbor)
found_unvisited = True
else:
# Dismiss "cycle" if it's just two nodes connected to each other
if (neighbor != cycle_stack[-2]):
# Cycle found
# Compare with current longest cycle
# Search current_stack to find index of this visited node
for i, possibility in enumerate(current_stack):
if possibility == neighbor:
length = len(cycle_stack) - (i + 1)
if (length > len(longest_cycle)):
longest_cycle = cycle_stack[i:]
if (!found_unvisited):
# This node has been fully explored
cycle_stack.pop()
return longest_cycle
Even if it is NP complete, that only means there's no clever algorithm to solve it, but solving it correctly the naive way can still be a worthwhile exercise.
def findLongestCycle(root):
longest_cycle = []
dfs_stack = [root]
cycle_stack = [root]
while (dfs_stack):
# DFS
node = dfs_stack.pop()
node.visited = True
# This boolean checks whether a node's neighbors have been fully explored
found_unvisited = False
for neighbor in node.neighbors:
if (!neighbor.visited):
# Add node to our stacks to explore
dfs_stack.append(neighbor)
cycle_stack.append(neighbor)
found_unvisited = True
else:
# Dismiss "cycle" if it's just two nodes connected to each other
if (neighbor != cycle_stack[-2]):
# Cycle found
# Compare with current longest cycle
# Search current_stack to find index of this visited node
for i, possibility in enumerate(current_stack):
if possibility == neighbor:
length = len(cycle_stack) - (i + 1)
if (length > len(longest_cycle)):
longest_cycle = cycle_stack[i:]
if (!found_unvisited):
# This node has been fully explored
cycle_stack.pop()
return longest_cycle
- Mei Li February 12, 2017