def add_linked_lists(ll1: LinkedList, ll2: LinkedList) -> LinkedList: sum_linked_list = LinkedList() pos1, pos2 = ll1.head, ll2.head carry, curr_position_sum = 0, 0 # generating the sum of the linked lists while pos1 or pos2: if pos1 == None: curr_position_sum = pos2.val + carry if curr_position_sum >= 10: carry, curr_position_sum = 1, curr_position_sum - 10 else: carry = 0 elif pos2 == None: curr_position_sum = pos1.val + carry if curr_position_sum >= 10: carry, curr_position_sum = 1, curr_position_sum - 10 else: carry = 0 else: curr_position_sum = pos2.val + pos1.val + carry if curr_position_sum >= 10: carry, curr_position_sum = 1, curr_position_sum - 10 else: carry = 0 sum_linked_list.add(curr_position_sum) # moving to the next value if pos1: pos1 = pos1.next if pos2: pos2 = pos2.next if carry == 1: sum_linked_list.add(1) return sum_linked_list
def merge_sorted_linked_list(list_of_LL: List[LinkedList]) -> LinkedList: k = len(list_of_LL) position_arr = [LL.head for LL in list_of_LL] sorted_ll = LinkedList() while any(position_arr): # finding the node with minimum value minimum = maxsize for i in range(k): if position_arr[i] is not None: if position_arr[i].val < minimum: minimum = position_arr[i].val position = i # generating new node if sorted_ll.head is None: sorted_ll.add(position_arr[position].val) curr_position = sorted_ll.head else: curr_position.next = Node(position_arr[position].val) curr_position = curr_position.next sorted_ll.length += 1 position_arr[position] = position_arr[position].next # resetting rear sorted_ll.rear = curr_position return sorted_ll
cumulative_sum_map[cumulative].next = node.next cumulative_sum_map[cumulative] = node node = node.next # resetting the linked list (removing dummy head and setting rear) linked_list.head = linked_list.head.next node = linked_list.head while node: linked_list.rear = node node = node.next return linked_list if __name__ == "__main__": linked_list = LinkedList() for elem in [3, 4, -7, 5, -6, 6]: linked_list.add(elem) print(delete_zero_sum(linked_list)) linked_list = LinkedList() for elem in [7, 4, -4, -7, 5, -6, 6]: linked_list.add(elem) print(delete_zero_sum(linked_list)) linked_list = LinkedList() for elem in [7, 4, -4, -7, 5, -6, 6, 10]: linked_list.add(elem) print(delete_zero_sum(linked_list)) """ SPECS: TIME COMPLEXITY: O(n)
def swap_nodes(ll: LinkedList) -> Node: node1 = ll.head node2 = ll.head.next while True: try: node1.val, node2.val = node2.val, node1.val node1, node2 = node1.next.next, node2.next.next except: break return ll.head if __name__ == "__main__": LL = LinkedList() LL.add(1) LL.add(2) LL.add(3) LL.add(4) print(LL) print(swap_nodes(LL)) """ SPECS: TIME COMPLEXITY: O(n) SPACE COMPLEXITY: O(1) """
def rearrange(ll: LinkedList) -> None: nodes_count = len(ll) nodes = [int(node) for node in ll] nodes.sort() for i in range(2, nodes_count, 2): nodes[i], nodes[i - 1] = nodes[i - 1], nodes[i] curr = ll.head for i in range(nodes_count): curr.val = nodes[i] curr = curr.next if __name__ == "__main__": LL = LinkedList() for i in range(1, 6): LL.add(i) print(LL) rearrange(LL) print(LL) """ SPECS: TIME COMPLEXITY: O(n) SPACE COMPLEXITY: O(n) """
if sorted_ll.head is None: sorted_ll.add(position_arr[position].val) curr_position = sorted_ll.head else: curr_position.next = Node(position_arr[position].val) curr_position = curr_position.next sorted_ll.length += 1 position_arr[position] = position_arr[position].next # resetting rear sorted_ll.rear = curr_position return sorted_ll if __name__ == "__main__": LL1 = LinkedList() LL1.add(2) LL1.add(25) LL1.add(70) LL2 = LinkedList() LL2.add(5) LL2.add(8) LL2.add(14) LL2.add(15) LL2.add(21) LL2.add(48) LL3 = LinkedList() LL3.add(0) LL3.add(90)
pos = len1 - len2 for _ in range(pos): pos1 = pos1.next # checking for intersecting node for _ in range(smaller_len): if pos1 is pos2: return pos1 pos1 = pos1.next pos2 = pos2.next # no intersection return None if __name__ == "__main__": ll1 = LinkedList() ll1.add(5) ll1.add(6) ll1.add(7) ll1.add(8) ll2 = LinkedList() ll2.add(1) ll2.add(2) ll2.add(3) ll2.add(4) ll3 = LinkedList() ll3.add(9) ll3.rear.next = ll1.head.next.next ll3.rear = ll3.rear.next.next ll3.length = 3
def create_linked_list(val: int) -> LinkedList: LL = LinkedList() while val > 0: LL.add(val % 10) val = val // 10 return LL
def sort(ll: LinkedList) -> LinkedList: ll.head = merge_sort(ll, ll.head) # reseting rear curr = ll.head while curr.next: curr = curr.next ll.rear = curr return ll if __name__ == "__main__": LL = LinkedList() for val in [6, 3, 7, 5, 30, 2, 50]: LL.add(val) print(LL) sort(LL) print(LL) print() LL = LinkedList() for val in [4, 1, -3, 99]: LL.add(val) print(LL) sort(LL) print(LL) """
length = len(ll) if length in (0, 1): return ll for _ in range(length): pos1, pos2 = randint(0, length - 1), randint(0, length - 1) node1, node2 = ll.head, ll.head for _ in range(pos1): node1 = node1.next for _ in range(pos2): node2 = node2.next node1.val, node2.val = node2.val, node1.val return ll if __name__ == "__main__": ll = LinkedList() for i in range(1, 6): ll.add(i) print(ll) shuffle(ll) print(ll) """ SPECS: TIME COMPLEXITY: O(n ^ 2) SPACE COMPLEXITY: O(1) """
pos2 = pos2.next # creating the cloned linked list from the generated nodes cloned_LL = LinkedList() cloned_LL.head = clone_head cloned_LL.length = ll.length cloned_LL.rear = pos2 return cloned_LL # adding the random pointer to Node class setattr(Node, "random_ptr", None) if __name__ == "__main__": LL = LinkedList() LL.add(1) LL.add(2) LL.add(3) LL.add(4) rand_join(LL, 0, 2) rand_join(LL, 2, 0) rand_join(LL, 1, 3) print("Original List:", LL) LL_clone = clone(LL) print("Cloned List:", LL_clone) # adding different elements to show that the clone is a deep copy
# ptr_k is k nodes away from the end while ptr_end is not None: ptr_end = ptr_end.next ptr_k = ptr_k.next # removing the required element temp = ptr_k.next ptr_k.next = temp.next temp.next = None ll.length -= 1 del temp if __name__ == "__main__": ll1 = LinkedList() for i in range(1, 10): ll1.add(i) print(ll1) delete_kth_last_node(ll1, 5) print(ll1) ll2 = LinkedList() for i in range(1, 4): ll2.add(i) print(ll2) delete_kth_last_node(ll2, 3) print(ll2) """ SPECS: TIME COMPLEXITY: O(n) SPACE COMPLEXITY: O(1)
ll.rear = ll.head ptr_prev, ptr_curr, ptr_next = None, ll.head, ll.head.next # reversing the flow while ptr_curr is not None: ptr_curr.next = ptr_prev ptr_prev, ptr_curr = ptr_curr, ptr_next if ptr_next is None: break ptr_next = ptr_next.next ll.head = ptr_prev if __name__ == "__main__": ll = LinkedList() for num in range(1, 6): ll.add(num) print(ll) reverse_inplace(ll) print(ll) ll = LinkedList() for num in range(1, 3): ll.add(num) print(ll) reverse_inplace(ll) print(ll) ll = LinkedList() for num in range(1, 2): ll.add(num) print(ll)
def pivot_linked_list(ll: LinkedList, k: int) -> None: ptr1, ptr2 = ll.head, ll.head length = len(ll) k = k % length for _ in range(length): if ptr2.val < k: ptr1.val, ptr2.val = ptr2.val, ptr1.val ptr1 = ptr1.next ptr2 = ptr2.next if __name__ == "__main__": LL = LinkedList() LL.add(5) LL.add(1) LL.add(8) LL.add(0) LL.add(3) print(LL) pivot_linked_list(LL, 3) print(LL) """ SPECS: TIME COMPLEXITY: O(n) SPACE COMPLEXITY: O(1)
def rotate_linked_list(ll: LinkedList, k: int = 0) -> None: k = k % ll.length for _ in range(k): temp = ll.head ll.head = ll.head.next temp.next = None ll.rear.next = temp ll.rear = ll.rear.next if __name__ == "__main__": LL = LinkedList() for num in [7, 7, 3, 5]: LL.add(num) print(LL) rotate_linked_list(LL, 2) print(LL) print() LL = LinkedList() for num in [1, 2, 3, 4, 5]: LL.add(num) print(LL) rotate_linked_list(LL, 3) print(LL) """ SPECS: