def sum_list_reverse_recursive_followup(ll1, ll2): """ using recursive solution to sum two linked list time complexity is O(N) - space complexity is O(N) :param ll1: :param ll2: :return: """ len1 = ll1.length() len2 = ll2.length() if len1 > len2: ll2.padding_before(len1 - len2, data=0) else: ll1.padding_before(len2 - len1, data=0) c, tot = sum_rec_followup(ll1.head, ll2.head) if c: tot = str(c) + tot # create tot linked list fin_ll = LinkedList() fin_ll.create([a for a in tot]) return fin_ll
def sum_list_reverse(ll1, ll2): """ sume the two list in reverse order - summing digit by digit time complexity is O(N) - Space complexity is O(1) :param ll1: :param ll2: :return: """ ll1 = ll1.head ll2 = ll2.head tot = '' carr = 0 while ll1 or ll2: ll1 = ll1 if ll1 else Node(0) ll2 = ll2 if ll2 else Node(0) s = ll1.data + ll2.data + carr b = s % 10 c = int(s / 10) if ll1.next is None: tot += str(s) else: tot += str(b) carr = c ll1 = ll1.next ll2 = ll2.next # create tot linked list fin_ll = LinkedList() fin_ll.create([a for a in tot]) return fin_ll
def create_looped_ll(): ll1 = LinkedList() ll1.create([1, 2, 3, 4, 5, 6, 7, 8]) for n in ll1.traverse(): pass n.next = ll1.head ll2 = LinkedList() ll2.create([-1, -2, -3]) for n in ll2.traverse(): pass n.next = ll1.head return ll2
def sum_list_reverse_recursive(ll1, ll2): """ same algorithm like sum_list_reverse but in recursive way - time complexity is O(N) - space complexity is O(N) :param ll1: :param ll2: :return: """ if ll1.head is None and ll2.head is None: print('linked lists are empty') exit() tot = sum_rec(ll1.head, ll2.head) # create tot linked list fin_ll = LinkedList() fin_ll.create([a for a in tot]) return fin_ll
def partition_1(linked_list, part_val): """ partition by creating two linked list (one for greater and one for less than target value) and attaching them together Using append the time complexity is O(N2) :param linked_list: :param part_val: :return: """ right_ll = LinkedList() left_ll = LinkedList() for item in linked_list.traverse(): if item.data >= part_val: right_ll.append(item.data) else: left_ll.append(item.data) for item in left_ll.traverse(): pass item.next = right_ll.head return left_ll
def partition_2(linked_list, part_val): """ partition by creating two linked list(one for greater and one for less than target value) and attaching them together creating the two linked list happens in one go so the time complexity is O(N) :param linked_list: :param part_val: :return: """ right_ll = LinkedList() left_ll = LinkedList() for item in linked_list.traverse(): tmp = Node(item.data) if item.data >= part_val: if right_ll.head is None: right_ll.head = tmp else: t = right_ll.head.next tmp.next = t right_ll.head.next = tmp else: if left_ll.head is None: left_ll.head = tmp else: if left_ll.head.next is None: last_left_elm = tmp t = left_ll.head.next tmp.next = t left_ll.head.next = tmp last_left_elm.next = right_ll.head return left_ll
def find_kth_recursive_2(llist, k): """ using recursive approach which returns value - time complexity is O(N) but space complexity is also O(N) :param llist: input linked list :param k: k integer :return: kth item from end of linked list """ indx, val = kth_rec_2(llist.head, k) return val if __name__ == '__main__': linked_list = LinkedList() linked_list.append_few([1, 5, 2, 3, 4, 1, 2, 5, 6, 5, 1]) linked_list.print_all() k = 7 # method1 val = find_kth(linked_list, k) print('\nKth item from the end of linked list is : {}'.format(val)) # method 2 find_kth_recursive(linked_list, k) # method 3 val = find_kth_recursive_2(linked_list, k) print('\nKth item from the end of linked list is : {}'.format(val))
stack.append(slow.data) fast = fast.next.next slow = slow.next # for case that the length of linked list is odd if fast is not None: slow = slow.next while slow is not None: if stack.pop() != slow.data: return False slow = slow.next return True if __name__ == '__main__': ll1 = LinkedList() ll1.create([]) print('\n Palindrome check is: {} '.format(palindrome(ll1))) # ll1.create([1, 2, 4, 2, 1]) ll1.create([1, 1]) print('\n Palindrome check is: {}'.format(palindrome(ll1))) print('\n Palindrome check using 2nd method is: {}'.format( palindrome_runner(ll1))) print('\n Palindrome check using 2nd method alternative is: {}'.format( palindrome_runner(ll1)))
right_ll.head = tmp else: t = right_ll.head.next tmp.next = t right_ll.head.next = tmp else: if left_ll.head is None: left_ll.head = tmp else: if left_ll.head.next is None: last_left_elm = tmp t = left_ll.head.next tmp.next = t left_ll.head.next = tmp last_left_elm.next = right_ll.head return left_ll if __name__ == '__main__': linked_list = LinkedList() linked_list.create([9, 5, 6, 3, 4, 1, 2, 5, 6, 5, 1]) linked_list = partition_1(linked_list, 5) linked_list.print_all() linked_list = partition_2(linked_list, 5) linked_list.print_all()
ll2.create([-1, -2, -3]) for n in ll2.traverse(): pass n.next = ll1.head return ll2 def print_result(node): if node: print('starting node of the loop is: {}'.format(node.data)) else: print('They is no loop in this linked list') if __name__ == '__main__': # ##### test the logic works for a looped case ll = create_looped_ll() node = find_loop_node(ll) print_result(node) # ##### test if it does not work for non looped ll1 = LinkedList() ll1.create([-1, -2, -3]) node = find_loop_node(ll1) print_result(node)
while True: slow = slow.next fast = fast.next.next if slow == fast: break slow = ll1.head while slow != fast: slow = slow.next fast = fast.next return slow.data if __name__ == '__main__': ll1 = LinkedList() ll1.create([1, 2, 3, 4, 5, 6, 7, 8]) print(loop_detection_hashmap(ll1)) for n in ll1.traverse(): pass n.next = ll1.head.next.next print('\nStart of the loop in this linked list is : {}'.format( loop_detection_hashmap(ll1))) print('\nStart of the loop in this linked list is : {}'.format( loop_detection_slow_fast_runner(ll1)))
break elif no1 < no2: for i, node in enumerate(link_list_2.traverse(), 1): if i == no2 - no1: ll2 = node.next break while ll1 != ll2: ll1 = ll1.next ll2 = ll2.next return ll1 if __name__ == '__main__': ll1 = LinkedList() ll1.create([1, 2, 3]) ll2 = LinkedList() ll2.create([4, 5]) for n in ll2.traverse(): pass n.next = ll1.head ll1.print_all() print('is list 1') ll2.print_all() print('is list 2') target = find_intersection_reverse_traverse(ll1, ll2) print('\nCommon Node has value : {}'.format(target.data))
if all([not l1.next, not l2.next]): b = t % 10 c = int(t / 10) return c, b c, res = sum_rec_followup(l1.next, l2.next) t = t + c b = t % 10 c = int(t / 10) return c, '{}{}'.format(b, res) if __name__ == '__main__': ll1 = LinkedList() ll1.create([7, 1, 6]) ll2 = LinkedList() ll2.create([5, 9, 2]) fin_ll = sum_list_reverse(ll1, ll2) fin_ll.print_all() ll3 = LinkedList() ll3.create([8, 5, 6, 7]) fin_ll = sum_list_reverse_recursive(ll1, ll3) fin_ll.print_all() ll2.create([5, 9, 5, 2]) fin_ll = sum_list_reverse_recursive_followup(ll1, ll2)