Advertisement
hoangreal

Compare nested lists

Oct 20th, 2024 (edited)
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.04 KB | Source Code | 0 0
  1. """
  2. Two lists, the elements in the list are either strings or lists, such as [a, [b, [c]], [d]].
  3. Give you two such lists to judge whether their contents are the same, REGARDLESS OF ELEMENT ORDER.
  4. """
  5.  
  6. ### STEP 1 ###
  7. class Node:
  8.     def __init__(self, val: str = "", children = {}):
  9.         self.val = val
  10.         self.children = children
  11.  
  12.     def create_child(self, other_node):
  13.         if other_node.val in self.children:
  14.             return
  15.         self.children[other_node.val] = other_node
  16.         return
  17.  
  18. ### STEP 2 ###
  19. def solve(nested_list1: list[str | list], nested_list2: list[str | list]) -> bool:
  20.     ### STEP 2 ###  
  21.     root1 = build_tree(nested_list1)
  22.     root2 = build_tree(nested_list2)
  23.    
  24.     ### STEP 4 -- YOU HAVE OPTIONS! ###
  25.     answer1 = compare(root1, root2)
  26.     answer = compare_bfs(root1, root2) # MAIN
  27.     assert answer == answer1
  28.    
  29.     ### STEP 5 ###
  30.     return answer
  31.  
  32. ### STEP 3 ###
  33. def build_tree(nested_list: list[str | list]) -> 'root Node':
  34.     """
  35.    Time Complexity: O(nlogn) -- n = number of elements if 'nested list' flattened
  36.    Space Complexity: O(n)    -- n = number of elements if 'nested list' flattened
  37.    """
  38.    
  39.     next_root_chars = []; next_nested_lists = []
  40.     for element in nested_list:
  41.         if isinstance(element, str):
  42.             next_root_chars.append(element)
  43.         else:
  44.             next_nested_lists.append(element)
  45.    
  46.     next_root_chars.sort()
  47.     next_child_nodes = [build_tree(element) for element in next_nested_lists]
  48.    
  49.     root = Node(val = ",".join(next_root_chars), children = {node.val: node for node in next_child_nodes})    
  50.     return root
  51.  
  52. ### STEP 4  
  53. def compare(root1: "Node", root2: "Node") -> bool:
  54.     """
  55.    Time Complexity: O(n) -- n = number of elements if 'nested list' flattened
  56.    Space Complexity: O(n)    -- n = number of elements if 'nested list' flattened
  57.    """    
  58.     if (not root1) or (not root2):
  59.         return (not root1) and (not root2)
  60.  
  61.     if root1.val != root2.val:
  62.         return False
  63.  
  64.     answer = True
  65.     shorter_map = root1.children if len(root1.children) < len(root2.children) else root2.children
  66.     longer_map = root2.children if len(root1.children) < len(root2.children) else root1.children
  67.     for next_val in shorter_map:
  68.         if next_val not in longer_map:
  69.             return False
  70.         answer &= compare(root1.children[next_val], root2.children[next_val])
  71.    
  72.     return answer
  73.  
  74. def compare_bfs(root1, root2) -> bool:
  75.     """
  76.    Use queue because the nested list
  77.    can be extremely deep, leading stack overflow.
  78.    
  79.    Time Complexity: O(n) -- n = number of elements if 'nested list' flattened
  80.    Space Complexity: O(n)    -- n = number of elements if 'nested list' flattened    
  81.    """
  82.     from collections import deque
  83.        
  84.     queue = deque([(root1, root2)])
  85.     while queue:
  86.         node1, node2 = queue.popleft()
  87.        
  88.         if (not node1) or (not node2):
  89.             if (not node1) and (not node2):
  90.                 continue
  91.             else:
  92.                 return False
  93.        
  94.         if node1.val != node2.val:
  95.             return False
  96.        
  97.         shorter_map = node1.children if len(node1.children) < len(node2.children) else node2.children
  98.         longer_map = node2.children if len(node1.children) < len(node2.children) else node1.children
  99.        
  100.         for next_val in shorter_map:
  101.             if next_val not in longer_map:
  102.                 return False
  103.             queue.append((node1.children[next_val], node2.children[next_val]))
  104.    
  105.     return True
  106.            
  107. ### STEP 6 ###
  108. assert solve(["abc"], ["bac"]) == False
  109. assert solve(["abc"], ["abc"]) == True
  110.  
  111. assert solve(["b", "a"], ["a", "b"]) == True
  112. assert solve([["a"], "b", "c"], ["a", "b", "c"]) == False
  113. assert solve([["a", "b"], "c"], ["c", ["b", "a"]]) == True
  114.  
  115. assert solve(['a', ['b', ['c']], 'd'], ['d', ['b', ['c']], 'a']) == True
  116. assert solve(['a', ['b', ['c']], ['d']], ['d', ['b', ['c']], 'a']) == False
  117. assert solve(['a', ['b', ['c']], ['d']], ['d', ['b', ['c']]]) == False
Tags: pinterest
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement