from utils import print_ll
from utils import Node


def add_two(l1, l2):
    curt = dummy = Node(-1)

    carry = 0
    while l1 or l2:
        v1 = v2 = 0
        if l1:
            v1 = l1.val
            l1 = l1.next
        if l2:
            v2 = l2.val
            l2 = l2.next
        val = (v1 + v2 + carry) % 10
        carry = (v1 + v2 + carry) // 10
        curt.next = Node(val)
        curt = curt.next

    if carry:
        curt.next = Node(carry)
    return dummy.next


if __name__ == '__main__':
    l1 = build_ll([2, 4, 3])
    l2 = build_ll([5, 6, 4])
    print_ll(add_two(l1, l2))
Exemple #2
0
Analyze and describe its complexity.
'''
from utils import print_ll
from utils import build_ll
from utils import Node
import heapq


def merge(head_list):
    '''
    list of heads
    '''
    curt = dummy = Node(-1)
    heap = []
    for head in head_list:
        heapq.heappush(heap, [head.val, head])

    while heap:
        _, head = heapq.heappop(heap)
        curt.next = head
        curt = curt.next
        if head.next:
            heapq.heappush(heap, [head.next.val, head.next])
    return dummy.next


if __name__ == '__main__':
    lists = [[1, 3, 4, 6], [0, 2, 5, 8], [7, 9]]
    lists = [build_ll(l) for l in lists]
    print_ll(merge(lists))
'''
Given a sorted linked list, delete all duplicates such that each element appear only once.

For example,
Given 1->1->2, return 1->2.
Given 1->1->2->3->3, return 1->2->3.
'''
from utils import build_ll
from utils import print_ll


def delete_duplicates(head):
    if not head or not head.next:
        return head

    curt = head
    while curt.next:
        if curt.val == curt.next.val:
            curt.next = curt.next.next
        else:
            curt = curt.next
    return head


if __name__ == '__main__':
    head = build_ll([1, 1, 2, 3, 3])
    print_ll(delete_duplicates(head))
Exemple #4
0
    '''
    if not head or not head.next:
        return head

    slow, fast = head, head.next
    while fast and fast.next:
        fast = fast.next.next
        slow = slow.next
    return slow


if __name__ == '__main__':
    print('insert')
    head = utils.build_ll([1, 2, 4, 5])
    head = insert(head, 3)
    utils.print_ll(head)
    head = insert(head, 0)
    utils.print_ll(head)
    head = insert(head, 6)
    utils.print_ll(head)
    print('=== ===')
    print('remove')
    head = remove(head, 3)
    utils.print_ll(head)
    head = remove(head, 0)
    utils.print_ll(head)
    head = remove(head, 6)
    utils.print_ll(head)
    utils.print_ll(remove(utils.build_ll([3, 3, 3, 2, 4]), 3))
    print('=== ===')
    print('reverse')
Exemple #5
0
Given 1->2->3->4, you should return the list as 2->1->4->3.

Your algorithm should use only constant space. You may not modify the values in
 the list, only nodes itself can be changed.
'''
from utils import print_ll
from utils import build_ll
from utils import Node


def rotate(head):
    prev = dummy = Node(-1)
    curt = dummy.next = head
    while curt and curt.next:
        next = curt.next
        temp = next.next

        prev.next = next
        next.next = curt
        curt.next = temp

        prev = curt
        curt = temp

    return dummy.next


if __name__ == '__main__':
    head = build_ll([1, 2, 3, 4])
    print_ll(rotate(head))
Exemple #6
0
from utils import Node


def remove_duplicates_II(head):
    if not head or not head.next:
        return head

    prev = dummy = Node(-1)
    curt = head
    is_dup = False
    while curt.next:
        if curt.val == curt.next.val:
            curt.next = curt.next.next
            is_dup = True
        else:
            if is_dup:
                prev.next = curt.next
            else:
                prev.next = curt
                prev = prev.next
            curt = curt.next
            is_dup = False
    if is_dup:
        prev.next = None
    return dummy.next


if __name__ == '__main__':
    head = build_ll([1, 1, 2, 3, 3])
    print_ll(remove_duplicates_II(head))
from utils import print_ll
from utils import build_ll
from utils import Node


def rotate(head, k):
    if not head or not k:
        return head

    tail = prev = dummy = Node(-1)
    dummy.next = head

    for _ in range(k):
        if not tail:
            return head
        tail = tail.next

    while tail.next:
        prev = prev.next
        tail = tail.next

    new_head = prev.next
    prev.next = None
    tail.next = head
    return new_head


if __name__ == '__main__':
    head = build_ll([1, 2, 3, 4, 5])
    print_ll(rotate(head, 2))
Exemple #8
0
For example,
Given 1->4->3->2->5->2 and x = 3,
return 1->2->2->4->3->5.
'''
from utils import print_ll
from utils import build_ll
from utils import Node


def partition(head, k):
    less_head = lcur = Node(-1)
    great_head = gcur = Node(-1)

    while head:
        if head.val < k:
            lcur.next = head
            lcur = lcur.next
        else:
            gcur.next = head
            gcur = gcur.next
        head = head.next

    gcur.next = None
    lcur.next = great_head.next
    return less_head.next


if __name__ == '__main__':
    head = build_ll([1, 4, 3, 2, 5, 2])
    print_ll(partition(head, 3))
Exemple #9
0
   After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Try to do this in one pass.
'''
from utils import build_ll
from utils import print_ll
from utils import Node


def remove_nth_from_end(head, n):
    if not head:
        return head

    curt = prev = dummy = Node(-1)
    dummy.next = head

    for _ in range(n):
        curt = curt.next

    while curt.next:
        curt = curt.next
        prev = prev.next
    prev.next = prev.next.next
    return dummy.next


if __name__ == '__main__':
    head = build_ll([1, 2, 3, 4, 5])
    print_ll(remove_nth_from_end(head, 2))
'''

from utils import build_ll
from utils import print_ll
from utils import Node


def merge(l1, l2):
    curt = dummy = Node(-1)

    while l1 and l2:
        if l1.val <= l2.val:
            curt.next = l1
            l1 = l1.next
        else:
            curt.next = l2
            l2 = l2.next
        curt = curt.next

    if l1:
        curt.next = l1
    else:
        curt.next = l2
    return dummy.next


if __name__ == '__main__':
    l1 = build_ll([1, 3, 5])
    l2 = build_ll([2, 4, 6])
    print_ll(merge(l1, l2))
Exemple #11
0
    while curt is not tail:
        temp = curt.next
        curt.next = prev.next
        prev.next = curt
        curt = temp
    head.next = tail


def reverse_k(head, k):
    prev = dummy = Node(-1)
    curt = dummy.next = head

    while True:
        tail = curt
        for _ in range(k):
            if not tail:
                return dummy.next
            tail = tail.next

        reverse(prev, curt, tail)
        curt.next = tail
        prev = curt
        curt = tail


if __name__ == '__main__':
    head = build_ll([1, 2, 3, 4, 5])
    print_ll(reverse_k(head, 2))
    head = build_ll([1, 2, 3, 4, 5])
    print_ll(reverse_k(head, 3))