예제 #1
0
    def partition(self, head, x):
        """
        :type head: ListNode
        :type x: int
        :rtype: ListNode
        """
        if head is None:
            return None

        dummy_before = ListNode(0)
        cur_before = dummy_before
        dummy_after = ListNode(0)
        cur_after = dummy_after
        cur_head = head
        while cur_head is not None:
            if cur_head.val < x:
                cur_before.next = cur_head
                cur_before = cur_before.next
            else:
                cur_after.next = cur_head
                cur_after = cur_after.next
            cur_head = cur_head.next

        cur_before.next = dummy_after.next
        cur_after.next = None

        return dummy_before.next
예제 #2
0
 def test_it_returns_the_correct_node(self):
     l = ListNode('1')
     last = last_of_list(l)
     self.assertEqual(last.value, '1')
     l = shift_list(ListNode('0'), l)
     last = last_of_list(l)
     self.assertEqual(last.value, '1')
예제 #3
0
    def sortList(self, head: ListNode) -> ListNode:
        if (head is None) or (head.next is None):
            return head

        # get length of linked list
        n = 0
        curr = head
        while curr:
            n += 1
            curr = curr.next

        header = ListNode()  # dummy header node
        header.next = head
        step = 1

        while step < n:
            curr = header.next
            tail = header

            while curr:
                left = curr
                right = split(left, step)
                curr = split(right, step)
                tail = merge(left, right, tail)

            #step *= 2
            step <<= 1

        return header.next
예제 #4
0
    def reverseKGroup(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        dumy = ListNode(0)
        dumy.next = head

        cur = dumy

        while cur is not None and cur.next is not None:
            sub_head = cur.next
            sub_tail = cur.next
            sub_len = 1
            for i in range(0, k - 1):
                sub_tail = sub_tail.next
                if sub_tail is None:
                    break
                sub_len += 1

            if sub_len == k:
                next_head = sub_tail.next
                new_head = self.revser_list(sub_head, k)
                sub_head.next = next_head
                cur.next = new_head
                cur = sub_head
            else:
                break
        return dumy.next
예제 #5
0
def sum_list(l1: Optional[ListNode[int]],
             l2: Optional[ListNode[int]]) -> Optional[ListNode[int]]:
    n1, n2, carry = l1, l2, 0
    head, runner = None, None
    while n1 or n2 or carry:
        v1 = n1.val if n1 else 0
        v2 = n2.val if n2 else 0

        total = v1 + v2 + carry
        carry = total // 10
        num = total % 10

        if n1:
            n1 = n1.next
        if n2:
            n2 = n2.next

        if not head:
            head = ListNode(num)
            runner = head
        else:
            runner.next = ListNode(num)
            runner = runner.next

    return head
예제 #6
0
def swap_nodes_in_pairs(head: ListNode) -> ListNode:
    # Create a dummy node pointing to head.
    dummy = ListNode(0)
    dummy.next = head
    current = dummy

    # Iterate through the list, starting from the dummy node
    # each time exchange the order of the two nodes after current.
    # Stop when there is only 0 or 1 node left.
    while current.next and current.next.next:
        # To avoid confusion, we can rename the two nodes to be
        # exchanged as node1 and node2.
        node1 = current.next
        node2 = current.next.next

        # Exchange node1 and node2:
        # current.next pointing to node2
        current.next = node2
        # node1.next pointing to node2.next
        node1.next = node2.next
        # node2.next pointing to node 1
        node2.next = node1

        # Move current to node1, we will exchange the two nodes
        # after node1 in the next iteration.
        current = node1

    return dummy.next
예제 #7
0
 def pad_zero(l: ListNode[int], n: int):
     head = l
     for _ in range(n):
         node = ListNode(0)
         node.next = head
         head = node
     return head
예제 #8
0
def partition(ll: LinkedList[T], x: T) -> LinkedList[T]:
    before_head, before_tail, after_head, after_tail = None, None, None, None
    # runner
    n = ll.head
    while n:
        if n.val < x and before_head == None:
            before_head = ListNode(n.val)
            before_tail = before_head
        elif n.val < x and before_head != None:
            before_tail.next = ListNode(n.val)
            before_tail = before_tail.next

        if n.val >= x and after_head == None:
            after_head = ListNode(n.val)
            after_tail = after_head
        elif n.val >= x and after_head != None:
            after_tail.next = ListNode(n.val)
            after_tail = after_tail.next

        n = n.next

    if not before_tail:
        return LinkedList(after_head)

    if before_tail:
        before_tail.next = after_head

    return LinkedList(before_head)
    def insert(self, head: ListNode, x: int) -> ListNode:
        if not head:  # case 0: empty list
            head = ListNode(x)
            head.next = head
            return head

        pre = head
        cur = head.next

        while 1:
            if pre.val <= x <= cur.val:  # case 1: insert in middle
                break

            if pre.val > cur.val:  # case 2: pre is tail (max), cur is head (min)
                if x > pre.val or x < cur.val:
                    break

            pre = cur
            cur = cur.next

            if pre == head:  # case 3: we've looped around once; all elts equal
                break

        pre.next = ListNode(x, cur)
        return head
예제 #10
0
 def addTwoNumbers(self, l1, l2):
     """
     :type l1: ListNode
     :type l2: ListNode
     :rtype: ListNode
     """
     dummy = ListNode(0)
     p = dummy
     add_on = 0
     while l1 is not None or l2 is not None:
         x = 0 if l1 is None else l1.val
         y = 0 if l2 is None else l2.val
         next_digit = x + y + add_on
         if next_digit < 10:
             p.next = ListNode(next_digit)
             add_on = 0
         else:
             p.next = ListNode(next_digit % 10)
             add_on = 1
         l1 = l1.next if l1 is not None else None
         l2 = l2.next if l2 is not None else None
         p = p.next
     if add_on > 0:
         p.next = ListNode(1)
     return dummy.next
예제 #11
0
def pad_list(head, n):
    """Pad a linked list with zeros before head"""
    for i in range(n):
        new_head = ListNode(0)
        new_head.next = head
        head = new_head
    return head
예제 #12
0
def add_lists(l1, l2):
    """
    Two lists contain digits stored in reverse order
    """
    p = res = None
    carry = 0
    while l1 is not None or l2 is not None:
        data1 = 0
        data2 = 0
        if l1 is not None:
            data1 = l1.data
            l1 = l1.next
        if l2 is not None:
            data2 = l2.data
            l2 = l2.next
        data = (data1 + data2 + carry) % 10
        carry = 1 if data1 + data2 + carry >= 10 else 0
        if res is None:
            res = create_list([data])
            p = res
        else:
            p.next = ListNode(data)
            p = p.next
    if carry > 0:
        p.next = ListNode(1)
    return res
예제 #13
0
def partition_list(head: ListNode, x: int) -> ListNode:
    """ Break Down and Concatenate
    We can break down the list into two parts:
    1. Nodes have value smaller than x;
    2. Nodes have value larger than or equal to x.


    Time Complexity - O(N) - Iterate through the list once.
    Space Complexty - O(1) - For pointers.
    """
    # Use two dummy nodes to store two break-down lists.
    s = smaller = ListNode(-1)
    l = larger = ListNode(-1)

    while head:
        if head.val < x:
            s.next = head
            s = s.next
        else:
            l.next = head
            l = l.next
        head = head.next

    # Last node of larger is the end.
    l.next = None
    # Concatenate two lists, as smaller will be followed by larger.
    s.next = larger.next

    return smaller.next
    def merge(l1: ListNode, l2: ListNode) -> ListNode:
        """ Merge two lists one element by one. """
        while l1 and l2:
            l1_temp = l1.next
            l2_temp = l2.next

            l1.next = l2
            l1 = l1_temp

            l2.next = l1
            l2 = l2_temp
def merge_two_sorted_lists(l1: ListNode, l2: ListNode) -> ListNode:
    """ Merge two sorted lists.
    """
    if not l1: return l2
    if not l2: return l1

    if l1.val <= l2.val:
        l1.next = merge_two_sorted_lists(l1.next, l2)
        return l1
    else:
        l2.next = merge_two_sorted_lists(l1, l2.next)
        return l2
예제 #16
0
 def removeNthFromEnd(self, head, n):
     dummy = ListNode(0)
     dummy.next = head
     slow = dummy
     fast = dummy
     for i in range(n):
         fast = fast.next
     while fast.next != None:
         slow = slow.next
         fast = fast.next
     slow.next = slow.next.next
     return dummy.next
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        if l1 is None:
            return l2

        if l2 is None:
            return l1

        if l1.val <= l2.val:
            l1.next = self.mergeTwoLists(l1.next, l2)
            return l1

        l2.next = self.mergeTwoLists(l1, l2.next)
        return l2
예제 #18
0
    def partial_sum(ln1: Optional[ListNode[int]],
                    ln2: Optional[ListNode[int]]):
        # the length of ln1 and ln2 is equal now
        n1, n2, carry, next_sum_node = ln1, ln2, 0, None
        if n1.next and n2.next:
            next_sum_node, carry = partial_sum(n1.next, n2.next)

        total = carry + n1.val + n2.val
        carry = total // 10
        sum = total % 10
        sum_node = ListNode(sum)
        sum_node.next = next_sum_node
        return sum_node, carry
예제 #19
0
 def mergeTwoLists2(self, l1: ListNode, l2: ListNode) -> ListNode:
     """
     Solution #2: recursively
     Time: O(n)
     Space: O(1)
     """
     if not l1: return l2
     if not l2: return l1
     if l1.val < l2.val:
         l1.next = self.mergeTwoLists2(l1.next, l2)
         return l1
     else:
         l2.next = self.mergeTwoLists2(l1, l2.next)
         return l2
    def removeElements(self, head: ListNode, val: int) -> ListNode:
        header = ListNode() # dummy header node
        header.next = head
        
        pre = header # last node that doesn't have target value
        
        while head:
            if head.val == val:
                pre.next = head.next    
            else:
                pre = head # pre.next

            head = head.next
            
        return header.next
예제 #21
0
def add_lists2(l1, l2):
    len1 = get_length(l1)
    len2 = get_length(l2)
    if len1 < len2:
        l1 = pad_list(l1, len2 - len1)
    else:
        l2 = pad_list(l2, len1 - len2)
    t = []
    carry = add_lists2_aux(l1, l2, t)
    res = create_list(t)
    if carry > 0:
        new_head = ListNode(1)
        new_head.next = res
        res = new_head
    return res
예제 #22
0
    def insertionSortList(self, head: ListNode) -> ListNode:
        if not head:
            return head

        header = ListNode()  # dummy header node for new linked list
        curr = head  # the node from original list to be inserted
        pre = header

        while curr:
            # save so we can update curr at end of loop
            next = curr.next

            # find where to insert
            if (not pre.next) or (pre.next.val >= curr.val):
                pre = header

            while pre.next and pre.next.val < curr.val:
                pre = pre.next

            # insert between pre and pre.next
            curr.next = pre.next
            pre.next = curr

            # update curr using saved "next"
            curr = next

        return header.next
def reverse_linked_list_recursion(head: ListNode) -> ListNode:
    """ Reverse with recursion
    We can assume the following nodes (after head) have been reversed and we 
    only need to reverse the current node and current.next.

    It'll be hard for human beings to understand the full process of recursion, 
    as our brains are not designed to push many items in stack, so we need to 
    focus on one stage (see reverse_linked_list_single_case.jpg for reference), 
    rather than try to understand the full process.

    For a single stage: 
    Given an input node head, reverse the linked list starting with head, and 
    return the reversed new head.

    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
def merge_k_sorted_lists_heapq(input_lists: list) -> ListNode:
    """ Solution - Min Heap
    We first insert the first element (also smallest as the lists are sorted) of each 
    linked list in a min heap. After this, we can take out the smallest element from 
    the heap and add it to the merged list. After removing the smallest element from the 
    heap, we can insert the next element of the same list into the heap. Repeat previous
    steps to populate the merged list in sorted order.

    Time Complexity - O(kn*logk) - the number of elements in the priority queue will be 
    less than k, so the time complexity for insertion and deletion will be O(logk), there 
    are at most k*n elements (every node is inserted and deleted once), so the total time 
    complexity will be O(kn*logk)
    Space Complexity - O(k) - for the priority queue (min-heap).
    """
    dummy = ListNode(-1)
    current = dummy
    min_heap = []

    # 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
예제 #25
0
def add(a, b):
    result = ListNode(0)
    result_head = result
    carry = 0

    while a or b or carry:
        a_digit = a.value if a else 0
        b_digit = b.value if b else 0
        a = a.next_node if a else None
        b = b.next_node if b else None
        digit_sum = a_digit + b_digit + carry
        new_digit = digit_sum % 10
        carry = digit_sum / 10
        result.next_node = ListNode(new_digit)
        result = result.next_node

    return result_head.next_node
예제 #26
0
def delete_duplicates_three_pointers(head: ListNode) -> ListNode:
    """ Three pointers
    The solution is similar to the two pointers one. The difference is in this 
    method, we are using `b` pointing to head.next rather than head. So to compare 
    whether two nodes have same values, we need to use: a.next.val == b.val.

    When the two pointers are pointing to different values, both a and b move forward 
    one step, while when they pointing to same values, there are some differentce.
    1. a.next pointing to b now;
    2. Pointer b has to handle bound problems, where b could be None, so we can't use 
    b = b.next directly, instead we have to see if b is already Nonem, so we won't get 
    an None has no next property error.

    Here `a` is called `preserve` and `b` is called `current`.

    Time Complexity - O(N) - Iterate the linked list once.
    Space Complexity - O(1) - Constant space for pointers.

    """
    # Edge cases, empty list or single element list.
    if not (head and head.next): return head

    # Create dummy node pointing to head
    dummy = ListNode(-1)
    dummy.next = head

    preserve = dummy
    current = head.next

    # Current could be None, such as 1 -> 1.
    while current:
        # If the nodes have different values, move forward one step.
        if preserve.next.val != current.val:
            preserve = preserve.next
            current = current.next
        else:
            # If the nodes have same values, then move current node until preseve and current
            # pointing to different values.
            while current and preserve.next.val == current.val:
                current = current.next
            # Different from two pointers solution, here a.next pointing to b.
            preserve.next = current
            # Current could pointing to None after the while loop before.
            current = current.next if current else None

    return dummy.next
예제 #27
0
def delete_duplicates(head: ListNode) -> ListNode:
    """ Two pointers
    To handle cases where the first node is also a duplicated node, we can 
    use dummy node to handle this. Firstly, we define two pointers `a` and 
    `b`, where `a` pointing to the dummy node, and `b` pointing to the head 
    node. 

    If the node `a` pointing to has a different value comparing to the node 
    `b` is pointing to, then both `a` and `b` move forward for one step. If 
    the values are the same, then only move `b`, and `b` keeps moving until 
    the values are different.

    Here we are comparing a.next.val == b.next.val. While the values that 
    the two pointers are pointing to are equal, we can use a while loop to
    keep `b` moving until we've filtered duplicated nodes.

    Here `a` is called `preserve` and `b` is called `current`.
    
    Time Complexity - O(N) - Iterate the linked list once.
    Space Complexity - O(1) - Constant space for pointers.
    """
    # Edge cases, empty list or single element list.
    if not (head and head.next): return head

    # Create dummy node pointing to head.
    dummy = ListNode(0)
    dummy.next = head

    preserve = dummy
    current = head

    while current and current.next:
        # If the nodes have different values, move forward one step.
        if preserve.next.val != current.next.val:
            preserve = preserve.next
            current = current.next
        else:
            # If the nodes have same values, then move current node until preseve and current
            # pointing to different values. Exclude all those nodes have same values.
            while current and current.next and preserve.next.val == current.next.val:
                current = current.next
            preserve.next = current.next
            current = current.next

    return dummy.next
예제 #28
0
 def addTwoNumbers(self, l1, l2):
     """
     :type l1: ListNode
     :type l2: ListNode
     :rtype: ListNode
     """
     head = ListNode(0)
     l = head
     rem = 0
     prevRem = 0
     while l1 is not None:
         val = (l1.val + l2.val) % 10
         l.next = ListNode(val + prevRem)
         prevRem = int(((l1.val + l2.val) - val) / 10)
         l = l.next
         l1 = l1.next
         l2 = l2.next
     return head.next
def addTwoNumbers(l1, l2):
    dummy_node = ListNode(0)
    p1 = l1
    p2 = l2
    carry = 0
    curr = dummy_node
    while p1 != None or p2 != None:
        x = p1.val if p1 != None else 0
        y = p2.val if p2 != None else 0
        sum = carry + x + y
        carry = sum//10
        curr.next = ListNode(sum%10)
        curr = curr.next
        if p1 != None: p1 = p1.next
        if p2 != None: p2 = p2.next
    if carry > 0:
        curr.next = ListNode(carry)
    return dummy_node.next
예제 #30
0
def swap_pairs(head):
    """
    :type head: ListNode
    :rtype: ListNode
    """
    node = ListNode(-1)
    node.next = head
    pre = node
    while pre.next and pre.next.next:
        l1 = pre.next
        l2 = pre.next.next
        nxt = l2.next
        l1.next = nxt
        l2.next = l1
        pre.next = l2
        pre = l1

    return node.next
예제 #31
0
 def addTwoNumbers(self, A, B):
     r = ListNode(0)
     head = r
     rem = 0
     while A is not None or B is not None:
         a = 0
         if A:
             a = A.val
         b = 0
         if B:
             b = B.val
         v = a + b + rem
         rem = 0
         if v > 9:
             rem = 1
             v = int(str(v)[1])
         r.next = ListNode(v)
         r = r.next
         if A:
             A = A.next
         if B:
             B = B.next
     if rem:
         r.next = ListNode(rem)
     r = head.next
     cnt = 0
     n = 0
     while r is not None:
         if r.val == 0:
             cnt += 1
         else:
             cnt = 0
         n += 1
         r = r.next
     # print n, cnt
     r = head.next
     if cnt:
         for i in range(n - cnt - 1):
             r = r.next
         r.next = None
     # print l2a(head.next)
     return head.next
예제 #32
0
            if tmp >= 10:
                carryover = tmp / 10
                tmp = tmp % 10
            else:
                carryover = 0
            
            lcount.val = tmp
            ltmp = lcount   
            lcount = lcount.next
            
        if carryover > 0:
            ltmp.next = ListNode(carryover)
        
        return lhead

l1 = ListNode(2)
l1.next = ListNode(4)
l1.next.next = ListNode(3)
#print l1

l2 = ListNode(5)
l2.next = ListNode(6)
l2.next.next = ListNode(4)
#print l2

sol = Solution()
print sol.addTwoNumbers(l1,l2)

l3 = ListNode(1)
l4 = ListNode(9)
l4.next = ListNode(9)