Пример #1
0
                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([])))
Пример #2
0
    """ 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))
Пример #3
0
    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))
Пример #4
0
                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))
Пример #7
0
思路:在单向链表中删除一个节点,常规思路无疑是从链表的头节点开始,顺序遍历来查找要删除的节点,并在链表中删除该节点,需要注意的是这种方式下给定的往往是节点值,而非节点指针,此时时间复杂度为 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])))
Пример #9
0
"""
题目:反转链表;定义一个函数,输入一个链表的头结点,反转该链表并输出反转后的头结点
思路:假设链表为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]))))
Пример #10
0
        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))