# end of binary tree return False # Current level match up and next node match up with either child node return probe_head.val == probe_root.val and \ (downward_probe(probe_head.next, probe_root.left) or downward_probe(probe_head.next, probe_root.right)) if not root: # Empty tree return False # Start downward path from probe_root # or wait until child node to start downward path return downward_probe(head, root) or is_sub_path( head, root.left) or is_sub_path(head, root.right) test_cases = [ ([4, 2, 8], [1, 4, 4, None, 2, 2, None, 1, None, 6, 8, None, None, None, None, 1, 3], True), ([1, 4, 2, 6], [1, 4, 4, None, 2, 2, None, 1, None, 6, 8, None, None, None, None, 1, 3], True), ([1, 4, 2, 6, 8], [1, 4, 4, None, 2, 2, None, 1, None, 6, 8, None, None, None, None, 1, 3], False) ] for build_list, build_tree, expected_output in test_cases: assert is_sub_path( LinkedList.create_linked_list(build_list).head, ConstructTree.build_tree_leetcode(build_tree).root) is expected_output
fast_pointer = slow_pointer = head prev_pointer = None while fast_pointer and fast_pointer.next: fast_pointer = fast_pointer.next.next tmp_pointer = slow_pointer.next slow_pointer.next = prev_pointer prev_pointer = slow_pointer slow_pointer = tmp_pointer if fast_pointer: # odd length case slow_pointer = slow_pointer.next while slow_pointer: if slow_pointer.val != prev_pointer.val: return False slow_pointer = slow_pointer.next prev_pointer = prev_pointer.next return True test_cases = [([1, 2, 2, 1], True), ([1, 2], False), ([1, 2, 3, 4, 5, 4, 3, 2, 1], True), ([1, 2, 3, 4, 4, 3, 2, 1], True), ([1, 2, 3, 4, 5, 4, 2, 1], False), ([1, 2, 3, 4, 5, 6, 3, 2, 1], False), ] for test_list, expected_output in test_cases: assert is_palindrome(head=LinkedList.create_linked_list(test_list).head) is expected_output
elif carry_over: current_node.next = ListNode(carry_over) return dummy_node.next test_cases = [ ([2, 4, 3], [5, 6, 4], [7, 0, 8]), ([0], [0], [0]), ([1, 8], [0], [1, 8]), ([9, 9, 9, 9, 9, 9, 9], [9, 9, 9, 9], [8, 9, 9, 9, 0, 0, 0, 1]), ([ 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 9 ], [ 5, 6, 4, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 2, 4, 3, 9, 9, 9, 9 ], [ 7, 0, 8, 4, 8, 6, 4, 8, 6, 4, 8, 6, 4, 8, 6, 4, 8, 6, 4, 8, 6, 4, 8, 6, 4, 8, 6, 4, 8, 6, 4, 8, 6, 4, 8, 6, 4, 8, 6, 4, 8, 6, 4, 8, 6, 4, 8, 6, 4, 8, 6, 4, 8, 6, 4, 8, 6, 1, 4, 3, 9, 1 ]), ] for input_1, input_2, expected_output in test_cases: assert add_two_number( l1=LinkedList.create_linked_list(input_1).head, l2=LinkedList.create_linked_list( input_2).head).list_from_node() == expected_output
assert not new_bst.look_up(14) for i in range(len(values)): deletion_tree = deepcopy(new_bst) assert deletion_tree.delete_node(values[i]) assert deletion_tree.is_valid() # print('Deleted: %d, Remaining: %s' % (values[i], str(deletion_tree.traversal()))) assert deletion_tree.traversal() == values[:i] + values[i + 1:] expected_values = [6, 7, 8, 9, 10, 11, 12, 13] assert new_bst.traverse_range(6, 13) == expected_values assert new_bst.traverse_range(6, 14) == expected_values assert new_bst.traverse_range(5.5, 13) == expected_values sorted_list = list(range(1, 11)) head = LinkedList.create_linked_list(sorted_list) new_bst = BST(head) assert new_bst.traversal() == sorted_list assert new_bst.is_balanced() new_bst = BST([-1]) new_bst.root.right = TreeNode(1) new_bst.root.right.left = TreeNode(-1) assert new_bst.is_valid() new_bst = BST([1]) new_bst.root.left = TreeNode(-1) new_bst.root.left.right = TreeNode(1) assert not new_bst.is_valid() new_bst = BST([1, 3, 4])
]), (list(range(9)), [ 0, 8, 1, 7, 2, 6, 3, 5, 4, ]), ([ 1, ], [ 1, ]), ([ 1, 2, ], [ 1, 2, ]), ] for test_input, test_output in test_cases: test_head = LinkedList.create_linked_list(test_input).head assert test_head.list_from_node() == test_input reorder_list(head=test_head) assert test_head.list_from_node() == test_output
:param head: head of a linked list, can be None :param val: remove all elements from linked list that equals to val :return: head of the remaining linked list, return None if nothing left """ while head and head.val == val: head = head.next if head is None: return None current_node = head while current_node.next: if current_node.next.val == val: current_node.next = current_node.next.next else: current_node = current_node.next return head N, l = 1000, 300 a, b = -100, 100 for i in range(N): test_target = randint(a, b) test_input_list = [test_target] + [randint(a, b) for _ in range(l)] test_output_list = list(filter(lambda x: x != test_target, test_input_list)) get_output = remove_elements( LinkedList.create_linked_list(test_input_list).head, test_target) assert get_output.list_from_node() == test_output_list assert remove_elements( LinkedList.create_linked_list([1] * randint(10, 50)).head, 1) is None assert remove_elements(None, 1) is None
""" dummy_node = probe_node = proceeding_node = ListNode(0, next=head) for _ in range(n): # 1 <= n <= length of list guaranteed; does not need to check for boundary condition probe_node = probe_node.next while probe_node.next: probe_node = probe_node.next proceeding_node = proceeding_node.next proceeding_node.next = proceeding_node.next.next return dummy_node.next test_cases = [ ([1, 2, 3, 4, 5], 1, [1, 2, 3, 4]), ([1, 2, 3, 4, 5], 2, [1, 2, 3, 5]), ([1, 2, 3, 4, 5], 5, [2, 3, 4, 5]), ([1], 1, []), ([1, 2], 1, [1]), ([5, 6, 9, 8, 6, 4, 5, 1, 9, 8, 7, 2, 8, 6, 8, 3, 5, 8, 6], 17, [5, 6, 8, 6, 4, 5, 1, 9, 8, 7, 2, 8, 6, 8, 3, 5, 8, 6]), ] for test_list, test_n, expected_output in test_cases: return_head = remove_nth_node( LinkedList.create_linked_list(test_list).head, test_n) if expected_output: assert return_head.list_from_node() == expected_output else: assert return_head is None
test_cases = [ ([1, 2, 3, 4, 5, 6], 2, 5), ([1, 2, 3, 4, 5], 2, 4), ([5], 1, 1), ([-5, 4, -2, -2, -2, 3, -3], 6, 6), ([ -18, -29, 30, 10, -45, -93, 9, -4, -52, 91, 61, 91, 19, 32, -100, 34, 38, 99, -93, -37, 73, -67, -29, 52, 6, -50, -87, -33, 6, -72, 72, 89, -51, -48, -52, -45, -41, 7, 1, -42, -3, -38, -52, 66, 44, 99, 0, -19, 47, 7, 44, 19, -10, 65, -30, 96, -86, -17, -87, -29, -39, 85, -41, -39, 87, -43, -34, -54, 65, 67, 4, -39, 79, 2, -73, 23, 0, -23, 54, 97, 34, -2, -35, -77, -88, -14, 69, 78, 19, 82, -52, 81, 17, -43, 92, 3, 14, -43, 49, -22, 74, -98, -10, 53, 4, -33, -75, 54, 44, 79, 50, -73, -74, 66, -50, -61, -49, -82, -84, 70, -100, -86, 0, 17, -29, -59, 70, 85, -2, 19, -87, -78, -29, -47, 75, 26, -30, 100, -21, 64, 28, 80, 91, 55, 45, -60, 94, 46, -42, 60, 15, -92, 74, -85, -25, -56, -44, -55, 79, 5, 14, 42, -23, 35, 95, -49, -40, -86, -100, -10, 78, 28, -31, 68, -18, 64, -93, -75, -41, -84, 85, 74, 75, 8, 39, -100, 2, 46, 96, -69, -100, -41, 73, -23, 94, 18, -22, -46, 32, -22, 44, 10, 56, 63, -23, 89, -24, -65, -87, 35, -99, 49, 8, 76, -44, 98, 26, 9, 43, 21, 40, -7, 80, 12, 70, 74, 80, -53, -73, 12, -25, 21, 72, -70, -17, -52, -82, 59, -67, 83, -7, -66, 31, 51, 61, 37, 48, -14, -55, -60, 58, 85, 33, 37, -53, -48, -40, -74, -51, -63, -12, 24, 58, -41, 5, 91, -42, -27, 49, -9, -95, 92, -24, 36, -7, 87, -77, 91, -78, -82, 82, 80, 54, -36, -33, -100, 17, 27, 77, 16, 65, -35, -60, -28, 24, -5, -37, 82, 18, 62, -77, 24, 4, -1, -41 ], 209, 286), ] for test_list, test_left, test_right in test_cases: assert reverse_between(LinkedList.create_linked_list(test_list).head, test_left, test_right).list_from_node() == \ test_list[:test_left - 1] + list(reversed(test_list[test_left - 1: test_right])) + test_list[test_right:]
if current_b.next: # traverse down the list current_b = current_b.next elif continue_b: # switch to list a to finish the remaining len_a steps current_b, continue_b = head_a, False else: # cap out at len_a + len_b + len_c steps # no need to traverse more return None return current_a test_cases = [ ([4, 1], [5, 6, 1], [8, 4, 5]), ([1, 9, 1], [3], [2, 4]), ([2, 6, 4], [1, 5], []), ([4, 1], [5, 6, 1], [8, 4, 5]), ([2, 6, 4], [2, 6, 4], []), ] for list_a, list_b, list_c in test_cases: test_head_a = LinkedList.create_linked_list(list_a).head test_head_b = LinkedList.create_linked_list(list_b).head test_head_c = LinkedList.create_linked_list(list_c).head test_head_a.last_node().next = test_head_c test_head_b.last_node().next = test_head_c assert get_intersection_node(head_a=test_head_a, head_b=test_head_b) is test_head_c
current_node.next = l2 return dummy_head.next test_cases = [ ([1, 2, 4], [1, 3, 4], [1, 1, 2, 3, 4, 4]), ([], [], []), ([], [0], [0]), ([ -20, -19, -17, -17, -13, -5, -5, -4, -1, -1, 0, 1, 11, 16, 18, 19, 20, 21, 21, 22, 22, 23, 25, 28, 29 ], [ -30, -27, -22, -21, -18, -17, -17, -13, -13, -5, -4, -1, 0, 6, 7, 8, 10, 15, 25, 27 ], [ -30, -27, -22, -21, -20, -19, -18, -17, -17, -17, -17, -13, -13, -13, -5, -5, -5, -4, -4, -1, -1, -1, 0, 0, 1, 6, 7, 8, 10, 11, 15, 16, 18, 19, 20, 21, 21, 22, 22, 23, 25, 25, 27, 28, 29 ]), ] for test_l1_list, test_l2_list, expected_output in test_cases: if expected_output: assert merge_two_sorted_lists(LinkedList.create_linked_list(test_l1_list).head, LinkedList.create_linked_list(test_l2_list).head).list_from_node() \ == expected_output else: assert merge_two_sorted_lists( LinkedList.create_linked_list(test_l1_list).head, LinkedList.create_linked_list(test_l2_list).head) is None
greater_current.next = head greater_current = head head = head.next greater_current.next = None less_current.next = greater_dummy.next return less_dummy.next test_cases = [ ([1, 4, 3, 2, 5, 2], 3), ([2, 1], 2), ([ -4, -4, -6, 8, 3, 7, -5, -8, 0, -3, -5, 5, -1, -3, -4, 3, 4, 0, -3, -6, 9, 4, -7, -6, -8 ], 9), ([ -21, -59, 4, -99, 84, -65, -32, -80, 12, -45, 17, -52, 72, -51, -64, -37, -34, -28, 85, -3, -22, 1, 4, -2, 12, -70, -83, 48, -99, 31, -87, -19, 24, 18, -66, 8, 5, 2, -20, -83, 10, 49, -35, -66, 99, -46, -3, -83, -22, -65, 14, 8, -12, 71, -94, -100, -99, 75, 48, -98, -42, 62, -65, 82, -68, -78, -58, 37, -24, -26, 55, 86, -76, 72, -79, 75, -74, -30, 92, -43, 5, 7, 65, 93, -70, 24, 93, -69, -1, 42, 85, 58, -44, 73, -8, -12, 95, -13, 77, -29, 61, -16, -90, 37, -91 ], 53), ] for test_input, test_x in test_cases: assert partition(LinkedList.create_linked_list(test_input).head, test_x).list_from_node() == \ [x_i for x_i in test_input if x_i < test_x] + [x_i for x_i in test_input if x_i >= test_x]
""" from _Linked_List import ListNode, LinkedList def reverse_list(head: ListNode) -> ListNode: """ :param head: head of a singly linked list :return: the head of the reversed list """ previous_node, current_node = None, head while current_node: next_node = current_node.next current_node.next = previous_node previous_node, current_node = current_node, next_node return previous_node test_cases = [ [1, 2, 3, 4, 5], [1, 2], [], ] for test_input in test_cases: test_list = LinkedList.create_linked_list(test_input) test_list.head = reverse_list(head=test_list.head) if not test_input: assert test_list.head is None else: assert test_list.head.list_from_node() == test_input[::-1]
from random import randint from _Linked_Complex import DoubleLinkedList, ComplexLinkedList from _Linked_List import LinkedList, PrintableLinkedList, ListNode test_node = ListNode(0) assert test_node.last_node().val == 0 assert test_node.count_to_last() == 1 node_list = [1, 2, 3, 4, 5] linked_list = LinkedList.create_linked_list(node_list) assert node_list == linked_list.head.list_from_node() assert linked_list.head.last_node().val == 5 assert len(linked_list) == len(node_list) point_to = linked_list.head expected_len = len(node_list) while point_to: assert point_to.count_to_last() == expected_len point_to = point_to.next expected_len -= 1 assert LinkedList.create_linked_list([]).midpoint_of_list() == (0, None) for list_len in range(1, 8): midpoint_index, midpoint = LinkedList.create_linked_list( list(range(1, list_len + 1))).midpoint_of_list() expected_index = list_len // 2 assert midpoint_index == expected_index and midpoint.val == midpoint_index + 1 printable_list = PrintableLinkedList.create_linked_list(node_list) separator = ', ' expected_output = separator.join([str(val) for val in node_list])
while l1: n1 = n1 * 10 + l1.val l1 = l1.next while l2: n2 = n2 * 10 + l2.val l2 = l2.next n3 = n1 + n2 return_head = None while n3 > 0: return_head = ListNode(n3 % 10, next=return_head) n3 //= 10 return return_head if return_head else ListNode(0) test_cases = [ ([7, 2, 4, 3], [5, 6, 4], [7, 8, 0, 7]), ([2, 4, 3], [5, 6, 4], [8, 0, 7]), ([0], [0], [0]), ([9, 9, 3], [1], [9, 9, 4]), ([9, 9, 3], [7], [1, 0, 0, 0]), ([5, 5, 5], [4, 9, 5], [1, 0, 5, 0]), ] for add_two_numbers in [add_two_numbers_stack, add_two_numbers_int]: for test_l1_list, test_l2_list, expected_output in test_cases: assert add_two_numbers( LinkedList.create_linked_list(test_l1_list).head, LinkedList.create_linked_list( test_l2_list).head).list_from_node() == expected_output