Open In App

Python | Join cycle in list

Last Updated : 01 May, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Sometimes, while dealing with graph problems in competitive programming, we have a list of pairs and we need to find if there is a possible cycle in it, and print all the elements in that cycle. Let’s discuss certain way in which this problem can be tackled.

Method 1: Using yield + loop + generator The brute method to perform is to use a generator and keep printing the value if we know that the elements surely form a cycle and this is done by infinite loop and stopping when no more matches are found. 

Python3




# Python3 code to demonstrate working of
# Join cycle in list
# Using yield + loop + generator
 
# helper function to perform this task
def cycle(test_list, val, stop = None):
    temp = dict(test_list)
    stop = stop if stop is not None else val
    while True:
        yield (val)
        val = temp.get(val, stop)
        if val == stop: break
 
# initializing list
test_list = [[6, 7], [9, 6], [7, 9]]
 
# printing original list
print("The original list is : " + str(test_list))
 
# Join cycle in list
# Using yield + loop + generator
# printing result
print("The cycle elements are : ")
for ele in cycle(test_list, 6):
    print(ele)


Output : 

The original list is : [[6, 7], [9, 6], [7, 9]]
The cycle elements are : 
6
7
9

Time Complexity: O(n)
Space Complexity: O(n)

Method 2:  Use a recursive function

  1. cycle_recursive takes in four arguments: test_list, a list of pairs of values, val, the starting value of the cycle, stop, the optional stopping value of the cycle, and visited, the optional set of visited values.
  2. If stop is not provided, it is set to val.
  3. If visited is not provided, an empty set is created.
  4. The starting value val is added to the visited set and yielded.
    next_val is set to None.
  5. For each pair of values in test_list, if the first value of the pair is equal to val, the second value is set to next_val. Similarly, if the second value of the pair is equal to val, the first value is set to next_val.
  6. If next_val is not None and it has not been visited before, the function is recursively called with next_val as the new starting value, stop and visited as the same as before.
  7. If next_val is not None but has been visited before, it means that we have found a cycle, so the function is broken out of using the break keyword.
  8. If next_val is None or is equal to stop, it means we have reached the end of the cycle and the function is returned.
  9. Finally, an example usage of the function is provided using the same test_list as before. The function is called with val=6 and iterated over to print the cycle elements.

Python3




def cycle_recursive(test_list, val, stop=None, visited=None):
    if stop is None:
        stop = val
    if visited is None:
        visited = set()
    visited.add(val)
    yield val
    next_val = None
    for pair in test_list:
        if pair[0] == val:
            next_val = pair[1]
        elif pair[1] == val:
            next_val = pair[0]
        if next_val is not None and next_val not in visited:
            yield from cycle_recursive(test_list, next_val, stop, visited)
            break
    if next_val is None or next_val == stop:
        return
 
 
# example usage
test_list = [[6, 7], [9, 6], [7, 9]]
 
print("Original list:", test_list)
 
print("Cycle elements:")
for ele in cycle_recursive(test_list, 6):
    print(ele)


Output

Original list: [[6, 7], [9, 6], [7, 9]]
Cycle elements:
6
7
9

Time complexity: O(n^2) 
Auxiliary space: O(1), 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads