コード例 #1
0
                len_h2 -= 1
            # advance prev_head by 1
            prev_head = prev_head.next

        # if len_h1 > 0, it means len_h2 == 0
        # append the rest of h1 (and remember h2 and the rest of the list is linked to h1)
        if len_h1 > 0:
            prev_head.next = h1
        # otherwise len_h2 must > 0
        else:
            prev_head.next = h2

        # now we have completed the merge part, advance the prev_head to the last number of the merged list
        # one of len_h1 and len_h2 must be positive, reduce to 0
        while len_h1 > 0 or len_h2 > 0:
            prev_head = prev_head.next
            len_h1 -= 1
            len_h2 -= 1

        # this is the most important line, it connect the last element of the merged list to the next group
        # we have updated head to be the first element of the next group (if any)
        # thus we can avoid of having an infinite loop (since h1 and h2 are linked all the way to the end)
        # we are essentially skipping the repeating part (where the loop will arise) and move on to the next group
        prev_head.next = head

    return return_head


test = list2ListNode([4, 5, 10, 2, 3, 6, 7, 9])
print(ListNode2list(sortList_bottom_up(test)))
コード例 #2
0
        # put curr to the less_list
        else:
            if not l_head:
                l_head = curr
                l_last = curr
            else:
                assert (l_last is not None)
                l_last.next = curr
                l_last = curr

        # advance curr by one step
        curr = curr.next

    # if the greater_list is not empty
    if g_head:
        # cut whatever is behind the tail of the greater_list
        g_last.next = None

    # if the less_list is not empty, append it to the left of the greater_list
    if l_head:
        l_last.next = g_head
        return l_head
    # otherwise there is no nodes less than x in the linked list
    else:
        return g_head


test = list2ListNode([1, 4, 3, 2, 5, 2])
test_x = 3
print(ListNode2list(partition(test, test_x)))
            if slow.next == fast:
                slow = fast
            else:
                slow.next = fast.next
            fast = fast.next
        return dummy.next


# 递归
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        if head is None or head.next is None:
            return head
        if head.next and head.val == head.next.val:
            while head.next != None and head.val == head.next.val:
                head = head.next
            return self.deleteDuplicates(head.next)
        else:
            head.next = self.deleteDuplicates(head.next)
        return head


# 读写指针

list2ListNode([1, 2, 3, 3, 4, 4, 5])
コード例 #4
0
    # Priority queue is a queue with priority, and instead of first in first out,
    # the element with highest priority (minimum priority number) will be retrieved first
    # doing this allows us retrieve the node with the smallest value with O(logk),
    # but insertion can also take O(logk)
    # without priority queue, we can use the method in the first solution, find min node in a loop O(k)
    head = ListNode(-1)
    prev_node = head
    q = PriorityQueue()
    for ln in lists:
        if ln:
            # wrapper here and below to prevent priority queue from comparing listnodes with the same priority
            q.put(PrioritizedItem(ln.val, ln))
            # OR use q.put(Wrapper(ln))

    while not q.empty():
        node = q.get().item
        # OR use node = q.get().node
        prev_node.next = node
        prev_node = node
        if node.next:
            q.put(PrioritizedItem(node.next.val, node.next))
            # OR use q.put(Wrapper(node.next))
    return head.next


test_list = [[1, 4, 5], [1, 3, 4], [2, 6]]
# test_list = [[],[]]
test = [list2ListNode(in_ln) for in_ln in test_list]
print(ListNode2list(mergeKLists_priority_queue(test)))
コード例 #5
0
    while l1_stack or l2_stack:
        if len(l1_stack) == 0:
            l1_val, l2_val = 0, l2_stack.pop()
        elif len(l2_stack) == 0:
            l1_val, l2_val = l1_stack.pop(), 0
        else:
            l1_val, l2_val = l1_stack.pop(), l2_stack.pop()

        curr_sum = l1_val + l2_val + addone
        curr_node = ListNode(curr_sum % 10)
        curr_node.next = head
        head = curr_node

        if curr_sum >= 10:
            addone = 1
        else:
            addone = 0

    if addone == 1:
        new_head = ListNode(1)
        new_head.next = head
        return new_head
    else:
        return head


test_1 = list2ListNode([2])
test_2 = list2ListNode([8])
print(ListNode2list(addTwoNumbers(test_1, test_2)))
コード例 #6
0
            stack.append(curr_node)
            curr_node = curr_node.next
        # the one added the latest is the new head
        group_head = stack.pop()
        prev_node = group_head
        # save the next group
        next_group = group_head.next
        # loop until stack is empty
        while stack:
            curr_node = stack.pop()
            prev_node.next = curr_node
            prev_node = curr_node
        # now curr_node is the tail of the group (whose next is still the penultimate node, therefore a loop)
        # to break the loop, reset the next to next_group, note that cannot reset to None
        # since if this is the final group, then curr_node.next should point to the remaining nodes in the list
        curr_node.next = next_group
        # similar as above
        if i == 0:
            prev_tail = curr_node
            return_head = group_head
        else:
            prev_tail.next = group_head
            prev_tail = curr_node
        # similarly, update group tail to the next group
        curr_node = next_group
    return return_head


test = list2ListNode([1, 2, 3, 4, 5, 6, 7, 8, 9])
print(ListNode2list(reverseKGroup_stack(test, 3)))
コード例 #7
0
    slow = fast = head
    while slow and fast and fast.next:
        slow = slow.next
        fast = fast.next.next
    # next find the head of the second half
    if fast:
        # the length of the list is odd, slow.next is the head of the second half
        second_head = slow.next
    else:
        # the length of the list is even, slow is the head of the second half
        second_head = slow
    # reverse the second half
    reversed_second_head = reverse_list(second_head)

    # compare the reversed second half with the whole list
    # (note that we are only comparing the first half of the whole list though)
    # After comparing all nodes in the reversed second half, head should be either
    # 1) at the head of the second half (even list)
    # 2) one node before the second half (odd list)
    while reversed_second_head:
        if head.val == reversed_second_head.val:
            head = head.next
            reversed_second_head = reversed_second_head.next
        else:
            return False
    return True


test = list2ListNode([1])
print(isPalindrome(test))
コード例 #8
0
from utils import list2ListNode, ListNode2list, ListNode


def removeElements(head, val):
    """
    Linear search with pseudo head
    Time: O(n)
    Space: O(1)
    """
    if not head:
        return head
    prev_node = return_head = ListNode(-1)
    return_head.next = head
    while head:
        if head.val == val:
            prev_node.next = head.next
            head = head.next
        else:
            prev_node = head
            head = head.next
    return return_head.next


test = list2ListNode([1, 2, 6, 3, 4, 5, 6])
print(ListNode2list(removeElements(test, 6)))
コード例 #9
0
        # if curr_node is already larger than the last of the sorted node (prev_node)
        # then we don't need to move curr_node, simply increment the sorted list by one node
        if curr_node.val >= prev_node.val:
            prev_node = curr_node
            curr_node = curr_node.next
            continue
        # otherwise, curr_node is not immediately sorted as above
        # take curr_node out of the list
        prev_node.next = curr_node.next
        # insert curr_node to the sorted part by scanning from the start
        p = return_head
        while p.next.val <= curr_node.val:
            p = p.next
        # stop until p.val < curr_node.val < p.next.val
        # insert curr_node between p and p.next
        curr_node.next = p.next
        p.next = curr_node
        # get the next unsorted node
        curr_node = prev_node.next

    return return_head.next


test = list2ListNode([1, 5, 3, 4, 0])
print(
    ListNode2list(
        insertionSortList(test)
    )
)

コード例 #10
0
            # link prev (even) to the next node (even), thus removing curr from its original position
            prev.next = next_node
            # link the whole even list after curr (odd)
            curr.next = first_eve
            # link curr to the end of the odd list
            last_odd.next = curr

            # two possibilities at the end of the list
            # 1) next_node is None (the whole list has odd number of nodes)
            #    then break from the loop and we are done
            #    which means curr (before we have processed it) is the last element of the whole list

            # 2) next_node is the last node in the list (the whole list has even number of nodes)
            #    enter the if block but curr will be updated to None
            #    which means the loop will stop as well

            if next_node:
                # curr is now the last node in the odd list
                last_odd = curr
                # go to the next ODD node (remember next_node is always even)
                curr = next_node.next
                # update prev (even)
                prev = next_node
            else:
                break
    return head


test = list2ListNode([1, 2, 3, 4, 5, 6, 7])
print(ListNode2list(oddEvenList(test)))
コード例 #11
0
from utils import list2ListNode, ListNode2list, ListNode


def deleteDuplicates(head):
    """
    Delete neighbouring nodes with the same value
    Time: O(n)
    Space: O(1)
    """
    if not head:
        return head
    return_head = ListNode(-1)
    return_head.next = head

    # loop invariant:
    # All nodes in the list up to the pointer head do not contain duplicate elements.
    while head.next:
        if head.next.val == head.val:
            head.next = head.next.next
        else:
            head = head.next
    return return_head.next


test = list2ListNode([1, 1, 2, 3])
print(ListNode2list(deleteDuplicates(test)))
コード例 #12
0
        # keep advance right pointer until the gap from the first node is n
        elif i < n:
            i += 1
    # if the last node is to be removed
    if n == 1:
        left.next = None
    # if the i did not reach n before right pointer hit the last node
    # then n is greater or equal to the length (L) of the list
    # and since n is a valid number, it must be L
    # remove the first node
    elif i < n:
        return head.next
    # normal cases, note here left.next is the node we want to remove
    else:
        left.next = left.next.next
    return head


# test = [1,2,3,4,5]
# n= 2

# test = [1,2]
# n = 2

test = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
n = 7
test_ln = list2ListNode(test)

print(test)
print(ListNode2list(removeNthFromEnd_two_pointers(test_ln, n)))
コード例 #13
0
            left = head
            # cut the link of the first half to the second half
            slow.next = None

            # pseudo head to store the merged list, head will be the next node to return_head
            return_head = ListNode(-1)
            curr = return_head
            # merge the two lists, in every iteration, first link the left to the merged list then the right
            while left and right:
                left_next = left.next
                right_next = right.next
                # link first the left then the right
                curr.next = left
                curr.next.next = right
                # update the end of the merged list
                curr = right
                # move forward left and right
                left = left_next
                right = right_next
            # if right is still not empty
            if right:
                curr.next = right
            # else left is still not empty
            else:
                curr.next = left


test = list2ListNode([1, 2, 3, 4, 5])
reorderList(test)
print(ListNode2list(test))