def add_lists(lst1, lst2): h1 = lst1.head h2 = lst2.head ans = LinkedList() carry = 0 while h1 or h2: if not h1: result = h2.data + carry h1 = h1.next elif not h2: result = h1.data + carry h2 = h2.next else: result = h1.data + h2.data + carry h1 = h1.next h2 = h2.next carry = 1 if result >= 10 else 0 ans.append_to_tail(result - carry * 10) return ans
def delete_kth_last_node(ll: LinkedList, k: int) -> None: # case for head node removal if k == len(ll): temp = ll.head if len(ll) == 1: ll.head = None ll.rear = None else: ll.head = temp.next temp.next = None ll.length -= 1 del temp return # generic node removal ptr_end = ll.head ptr_k = ll.head # moving the ptr_end up by k nodes for _ in range(k + 1): if ptr_end is None: raise ValueError(f"Linked list contains less than {k} nodes") ptr_end = ptr_end.next # searching for the end of the linked list # ptr_k is trailing the ptr_end up by k nodes, when end pointer reaches the end, # 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
def test1(self): lst = LinkedList(1, 2, 3, 3, 4) required = LinkedList(1, 2, 3, 4) remove_duplicate_nodes(lst) self.assertEqual(lst, required)
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
def test4(self): lst1 = LinkedList(3, 1, 5) lst2 = LinkedList(5, 9, 2) required = LinkedList(8, 0, 8) ans = add_lists(lst1, lst2) self.assertEqual(ans, required)
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
def test3(self): lst = LinkedList(1, 1, 3, 1, 1) n = lst.get_node(3) remove_node_from_middle(n) required = LinkedList(1, 1, 1, 1) self.assertEqual(lst, required)
def reverse_inplace(ll: LinkedList) -> None: 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
def test5(self): lst = LinkedList(1, 2, 3, 4, 5) n = lst.get_node(3) lst.get_node(5).next = n self.assertEqual(is_circular(lst), True) lst1 = LinkedList(1, 2, 3, 4) self.assertEqual(is_circular(lst1), False)
def __init__(self, hashTableSize=defaultHashTableSize): # Should probably be named HashTableEntry. You get the point. self.buckets = [LinkedList() for x in range(0, hashTableSize)] # A quick lookup for has() and getKeys(). self.keys = {}
def add_node_sorted(ll: LinkedList, val: int) -> None: ll.length += 1 if not ll.head: ll.head = Node(val) ll.rear = ll.head elif val > ll.rear.val: ll.rear.next = Node(val) ll.rear = ll.rear.next else: pos = ll.head while pos.val < val: pos = pos.next temp = pos.val pos.val = val new_node = Node(temp) new_node.next = pos.next pos.next = new_node if pos == ll.rear: ll.rear = new_node
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 clone(ll: LinkedList) -> LinkedList: clone_head = ll.head pos1 = ll.head pos2 = ll.head.next # duplicating all elements (by value in the linked list) # [a -> b -> c becomes a -> a -> b -> b -> c -> c] for _ in range(ll.length): pos1.next = Node(pos1.val) pos1 = pos1.next pos1.next = pos2 pos1 = pos1.next if pos2 is None: break pos2 = pos2.next # setting the clone head to the proper position clone_head = clone_head.next pos1 = ll.head # setting the random pointer of the cloned linked list # (every 2nd element in the new linked list: a -> [a] -> b -> [b] -> c -> [c]) for _ in range(ll.length - 1): pos1.next.random_ptr = pos1.random_ptr pos1 = pos1.next.next # reverting the linked list to its original form pos1 = ll.head pos2 = ll.head.next for _ in range(ll.length - 1): pos1.next = pos2.next pos2.next = pos2.next.next pos1 = pos1.next if pos2.next == None: break 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
def delete_zero_sum(linked_list: LinkedList) -> LinkedList: cumulative = 0 cumulative_sum_map = {} dummy_head = Node(0) dummy_head.next = linked_list.head linked_list.head = dummy_head # removing 0 sum nodes using the property: # x -> y -> x [values (x and y) are cumulative sums] implies the linked list # contains x -> (y - x) -> -(y - x) and hence the nodes at the end can be removed # [this property can also be used to detect multiple nodes summing up to 0] node = linked_list.head while node: cumulative += node.val if cumulative in cumulative_sum_map: 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
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
def testNewLinkedList(self): self.new_list = LinkedList() assert self.new_list.head == None
cumulative += node.val if cumulative in cumulative_sum_map: 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:
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) """
fast = fast.next.next return slow 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)
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) """
def setup_class(self): print("Linked list tests") self.makeLinkedList = lambda self, initial_data=None: LinkedList( initial_data)
def __init__(self) -> None: self.List = LinkedList() self.start = None self.end = None
def test2(self): lst = LinkedList(1, 1, 3, 1, 1) self.assertEqual(find_nth(lst, 3), 3)
def create_linked_list(val: int) -> LinkedList: LL = LinkedList() while val > 0: LL.add(val % 10) val = val // 10 return LL
# 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 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)
from DataStructures.LinkedList import LinkedList from DataStructures.Element import Element # Test cases # Set up some Elements e1 = Element(1) e2 = Element(2) e3 = Element(3) e4 = Element(4) # Start setting up a LinkedList ll = LinkedList(e1) ll.append(e2) ll.append(e3) # Test get_position # Should print 3 print(ll.head.next.next.value) # Should also print 3 print(ll.get_position(3).value) # Test insert ll.insert(e4, 3) # Should print 4 now print(ll.get_position(3).value) # Test delete ll.delete(1) # Should print 2 now print(ll.get_position(1).value)
class TestLinkedList: new_list = LinkedList() def testNewLinkedList(self): self.new_list = LinkedList() assert self.new_list.head == None def testAddNode(self): self.new_list.addNode('node_1') assert self.new_list.head.data == 'node_1' def testGetLength(self): size = self.new_list.length() assert size == 1 self.new_list.addNode('node_2') size = self.new_list.length() assert size == 2 self.new_list.addNode('node_3') self.new_list.addNode('node_4') def testStr(self): print(self.new_list) def testDelOldestNode(self): node = self.new_list.delOldestNode() assert self.new_list.length() == 3 assert node == 'node_1' def testDelNewestNode(self): node = self.new_list.delNewestNode() assert self.new_list.length() == 2 assert node == 'node_4'
import sys sys.path.append("../") from DataStructures.LinkedList import LinkedList,Element try: print("Start LinkedList Tests ..") # Set up some Elements e1 = Element(1) e2 = Element(2) e3 = Element(3) e4 = Element(4) # Start setting up a LinkedList ll = LinkedList(e1) ll.append(e2) ll.append(e3) # Test cases # Should print 3 assert ll.head.next.next.value == 3 # Test get_position # Should print 3 assert ll.get_position(3).value == 3 # Test insert ll.insert(e4,3) # Should print 4 now
elif len1 > len2: 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
def distribute(a_list, val): c = LinkedList() #print('distribute ', a_list, "| val ", val) for elem in a_list: c.append(val + elem.data) return c