def test_add(self): linked = LinkedList() linked.add(5) self.assertIsNotNone(linked.head) self.assertIsNotNone(linked.tail) self.assertEqual(linked.head.value, 5) self.assertEqual(linked.tail.value, 5)
def merge_no_extra_space(list1, list2): """ This solution creates a new list but the nodes are actually the same from the original list, thus we don't create any new node. It works exactly the same as the other solution but instead of creating new nodes, we point the new list's next to the current item and then change the current to move forward (making sure we move forward with the resulting list too). Complexity in time is O(n + m) as well, but space is constant, although we modify the elements of the original lists. """ c1 = list1.head c2 = list2.head merged = LinkedList() if c1.value < c2.value: merged.head = c1 c1 = c1.next else: merged.head = c2 c2 = c2.next c3 = merged.head while c1 and c2: if c1.value < c2.value: c3.next = c1 c3 = c3.next c1 = c1.next else: c3.next = c2 c3 = c3.next c2 = c2.next c3.next = c1 if c1 else c2 return merged
def merge(list1, list2): """ This solution creates a new linked list and adds new node values while iterating on the two linked lists. When we find that an element of the first list is less than the one of the second, then we add a new node with the same value as the first and progress the pointer. Otherwise, we do the same for the other list. When one of the two pointers comes to tail, we copy the remaining items from the other list. Complexity in time is O(n + m) where n and m are the lengths of the 2 lists. Complexity in space is O(n + m) as well. """ c1 = list1.head c2 = list2.head merged = LinkedList() while c1 and c2: if c1.value < c2.value: merged.add(c1.value) c1 = c1.next else: merged.add(c2.value) c2 = c2.next while c1: merged.add(c1.value) c1 = c1.next while c2: merged.add(c2.value) c2 = c2.next return merged
def sort_k_linked_lists(*linked_lists): min_heap = heap.Heap(comp=lambda x, y: x.value < y.value) for lst in linked_lists: min_heap.insert(lst.head) result = LinkedList() while len(min_heap.items) > 0: item = min_heap.extract_min() if item.next: min_heap.insert(item.next) result.add(item.value) return result
def test_remove__many_elements_list(self): linked = LinkedList() linked.add(5) linked.add(0) linked.add(-1) linked.remove(1) self.assertEqual(linked.head.value, 5) self.assertEqual(linked.tail.value, -1) linked.remove(1) self.assertEqual(linked.head.value, 5) self.assertEqual(linked.tail.value, 5)
def test_remove__from_tail(self): linked = LinkedList() linked.add(5) linked.add(0) linked.add(-1) linked.remove(2) self.assertEqual(linked.head.value, 5) self.assertEqual(linked.tail.value, 0)
def test_add__consecutive(self): linked = LinkedList() linked.add(5) self.assertIsNotNone(linked.head) self.assertIsNotNone(linked.tail) self.assertEqual(linked.head.value, 5) self.assertEqual(linked.tail.value, 5) linked.add(0) self.assertIsNotNone(linked.head) self.assertIsNotNone(linked.tail) self.assertEqual(linked.head.value, 5) self.assertEqual(linked.tail.value, 0) linked.add(-1) self.assertIsNotNone(linked.head) self.assertIsNotNone(linked.tail) self.assertEqual(linked.head.value, 5) self.assertEqual(linked.tail.value, -1)
def test_remove__single_element_list(self): linked = LinkedList() linked.add(5) linked.remove(0) self.assertIsNone(linked.head) self.assertIsNone(linked.tail)
if fast.next is None or fast.next.next is None: return fast = fast.next.next if slow == fast: break if slow.next is None: return slow = lst.head while slow != fast: slow = slow.next fast = fast.next return slow if __name__ == '__main__': lst = LinkedList() lst.add('1') print get_start_of_loop(lst) lst = LinkedList() lst.add('a').add('b').add('c').add('d').add('e').add('f') lst.tail.next = lst.head.next.next print get_start_of_loop(lst) lst = LinkedList() lst.add('0').add('a').add('b').add('c').add('d').add('e').add('f').add('g').add('h') lst.tail.next = lst.head.next.next print get_start_of_loop(lst)