if newHeader is None: newHeader = p t = newHeader else: t.next = p t = t.next p = p.next else: if newHeader is None: newHeader = q t = newHeader else: t.next = q t = t.next q = q.next while p is not None: t.next = p p, t = p.next, t.next while q is not None: t.next = q q, t = q.next, t.next t.next = None return newHeader s = Solution() traverse(s.mergerLinkedList(build([1, 3, 5, 7]), build([2, 4, 6, 8]))) traverse(s.mergerLinkedList(build([1, 3, 5, 7, 7]), build([1, 3, 3, 5, 8]))) traverse(s.mergerLinkedList(build([1]), build([2]))) traverse(s.mergerLinkedList(build([]), build([])))
""" Recursion Time Complexity - O(N+M) - N, M are the total number of elements in the two linked lists. Space Complexity - O(N+M) - recursion stack. """ # Stop condition: when l1 or l2 is empty. if l1 is None: return l2 elif l2 is None: return l1 if l1.val <= l2.val: # Merge l1's next node and l2 as l1's new next node. l1.next = merge_two_sorted_lists_recursion(l1.next, l2) return l1 else: # Merge l2's next node and l1 as l2's new next node. l2.next = merge_two_sorted_lists_recursion(l1, l2.next) return l2 if __name__ == "__main__": l1 = create_linked_list([1, 2, 4, 5]) l2 = create_linked_list([1, 3, 4]) new_head = merge_two_sorted_lists(l1, l2) print(traverse(new_head)) l1 = create_linked_list([1, 2, 4, 5]) l2 = create_linked_list([1, 3, 4]) merged = merge_two_sorted_lists_recursion(l1, l2) print(traverse(merged))
return last def reverse_between_recursion(head: ListNode, m: int, n: int) -> ListNode: """ Reverse using recursion Assuming m - 1 is the first node and the folling will be similar to reverse the previous N nodes. """ # Stop condition if m == 1: return reverse_n(head, n) # Move foward until m - 1 is 1. head.next = reverse_between_recursion(head.next, m - 1, n - 1) return head if __name__ == "__main__": head = create_linked_list([1, 2, 3, 4, 5]) new_head = reverse_between(head, 2, 4) print(traverse(new_head)) head = create_linked_list([7, 9, 2, 10, 1, 8, 6]) new_head = reverse_between(head, 3, 6) print(traverse(new_head)) head = create_linked_list([1, 2, 3, 4, 5]) new_head = reverse_between_recursion(head, 2, 4) print(traverse(new_head))
else: prev.next = h2 h2 = h2.next c2 = c2 - 1 prev = prev.next prev.next = h1 or h2 # Move prev to the node before cur. while c1 > 0 or c2 > 0: prev = prev.next c1 -= 1 c2 -= 1 prev.next = cur interval *= 2 return dummy.next if __name__ == "__main__": head = create_linked_list([4, 2, 1, 3]) result = sort_list_top_down(head) print(traverse(result)) head = create_linked_list([4, 2, 1, 3]) result = sort_list_bottom_up(head) print(traverse(result))
# Put the root of each list in the min heap for root in input_lists: if root: heapq.heappush(min_heap, root) # Pop the smallest element from the min heap and add it to the result sorted list. while min_heap: node = heapq.heappop(min_heap) current.next = node current = current.next # If the element poped still have next node, then add it into the heap. if node.next: heapq.heappush(min_heap, node.next) return dummy.next if __name__ == "__main__": l1 = create_linked_list([2, 6, 8]) l2 = create_linked_list([3, 6, 7]) l3 = create_linked_list([1, 3, 4]) new_list = merge_k_lists_divide_and_conquer([l1, l2, l3]) print(traverse(new_list)) l1 = create_linked_list([1, 4, 5]) l2 = create_linked_list([1, 3, 4]) l3 = create_linked_list([2, 6]) result = merge_k_sorted_lists_heapq([l1, l2, l3]) print(traverse(result))
Time Complexity - O(N) - Iterate the list once. Space Complexity - O(N) - For recursion stack. """ # Recursion stop condition. if head == None or head.next == None: return head # Reverse the following nodes. # temp will be the last node or the head node for the reversed list. temp = reverse_linked_list_recursion(head.next) # Reverse - the next node after head shall point to head now. head.next.next = head # Pointing head to None to avoid dead loop. head.next = None # Always return the new head node. return temp if __name__ == "__main__": head = create_linked_list([1, 2, 3, 4, 5]) print(traverse(head)) reversed_head = reverse_linked_list(head) print(traverse(reversed_head)) reverted_head = reverse_linked_list_recursion(reversed_head) print(traverse(reverted_head))
思路:在单向链表中删除一个节点,常规思路无疑是从链表的头节点开始,顺序遍历来查找要删除的节点,并在链表中删除该节点,需要注意的是这种方式下给定的往往是节点值,而非节点指针,此时时间复杂度为 O(n) 而题目要求再O(1)时间内,因此需要另谋他法;例如,一个单链表如下:1->2->3->4->5,如果要删除节点3,除了从头查找外,我们也可以充分利用给定要删除节点的指针这一信息, 即可以用待删除节点的下一节点来覆盖待删除节点,然后删除下一节点。如果是前(n-1)个节点,对应时间复杂度为O(1),最后一个节点由于没有后续节点,因此需要从头开始查找待删除节点,此时时间复杂度为O(n), 但是最终的时间复杂度=(n-1+n)/2,仍然是O(1)时间复杂度 """ from linked_list import traverse, build class Solution(object): def deleteNode(self, header, toBeDeletedNode): if header == None or toBeDeletedNode == None: return header # 尾节点 if toBeDeletedNode.next is None: temp = header while temp is not None and temp.next != toBeDeletedNode: temp = temp.next temp.next = toBeDeletedNode.next else: temp = toBeDeletedNode.next toBeDeletedNode.val = temp.val toBeDeletedNode.next = temp.next return header s = Solution() header = build([1, 2, 3, 4, 5]) traverse(s.deleteNode(header, None)) traverse(s.deleteNode(header, header.next.next)) traverse(s.deleteNode(header, header.next.next.next.next)) traverse(s.deleteNode(header, header))
""" 题目:删除链表中重复的节点。例如,链表1->2->3->3->4->4->5 处理后为 1->2->5 思路:双指针,设双指针为pre,post;注意pre的下一节点始终是post """ from linked_list import build, traverse class Solution(object): def deleteeduplicativeNodes(self, header): # 如果是空或者只有一个节点,直接退出 if header is None or header.next is None: return header pre, post = header, header.next while post is not None: if pre.val == post.val: pre.next = post.next post = post.next else: pre = pre.next post = post.next return header s = Solution() header2 = build([1, 1, 2, 3, 4, 5]) traverse(s.deleteeduplicativeNodes(build([1, 2, 3, 3, 4, 4, 5]))) traverse(s.deleteeduplicativeNodes(build([1, 1, 2, 3, 4, 5]))) traverse(s.deleteeduplicativeNodes(build([1, 2, 3, 4, 5, 5, 5])))
""" 题目:反转链表;定义一个函数,输入一个链表的头结点,反转该链表并输出反转后的头结点 思路:假设链表为1->2->3->4->5:当链表为空或者只有一个节点时,直接返回,不做任何处理;当链表节点数多余1个时,用以下解法; 设遍历到p节点时,q指向p的下一节点;将q指向p,再将q的下一节点存为r节点,此时只需要将p和q节点往后移动一位即可; """ from linked_list import build, traverse class Solution(object): def reverseLinkedList(self, header): if header is None or header.next is None: return header p, q, r = header, header.next, None header.next = None while q is not None: r = q.next q.next = p p = q q = r header = p return header s = Solution() print(traverse(s.reverseLinkedList(build([1, 2, 3, 4, 5])))) print(traverse(s.reverseLinkedList(build([])))) print(traverse(s.reverseLinkedList(build([1]))))
return head # Swap two nodes, head is the first node while new head is # the second node. # First we use new_head to represent the second node new_head = head.next # Then we swap the nodes after the second head and it will # be the next of head as head is moving to the position of # the original second node. head.next = swap_nodes_in_pairs_recursion(new_head.next) # Pointing new_head's next to head as new_head has become # the new first node. new_head.next = head # Return the swapped node new_head. return new_head if __name__ == "__main__": odd_list = create_linked_list([1, 2, 3, 4, 5]) print(traverse(odd_list)) new_odd_list = swap_nodes_in_pairs(odd_list) print(traverse(new_odd_list)) even_list = create_linked_list([1, 2, 3, 4]) print(traverse(even_list)) new_even_list = swap_nodes_in_pairs(even_list) print(traverse(new_even_list)) result = swap_nodes_in_pairs_recursion(new_even_list) print(traverse(result))