Example #1
0
    node = l
    i = 0
    while node:
        if heads[i] is None:
            heads[i] = node
        if tails[i] is not None:
            tails[i].next = node
        tails[i] = node
        node = node.next
        tails[i].next = None
        i = (i+1) % k

    out_head = out_tail = None
    i = k-1
    while any(h is not None for h in heads):
        if heads[i] is not None:
            if out_head is None:
                out_head = heads[i]
            if out_tail is not None:
                out_tail.next = heads[i]
            out_tail = heads[i]
            heads[i] = heads[i].next
            out_tail.next = None
        i = (i-1) % k
    
    return out_head


l = Node.from_iterable(range(10))
print(kreverse(l, 3))
Example #2
0
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 __future__ import print_function
from linked_list import Node


def remove_duplicates(l):
    last_unique = l
    node = l.next

    while node:
        if node.val != last_unique.val:
            last_unique.next = node
            last_unique = node
        node = node.next

    last_unique.next = None

    return l


for l in (Node.from_iterable([1, 1, 2]), Node.from_iterable([1, 1, 2, 3, 3])):
    print('Before:', l)
    print('After:', remove_duplicates(l))
Example #3
0
"""
Rotate List
===========

Given a list, rotate the list to the right by k places, where k is non-negative.

For example:

Given 1->2->3->4->5->NULL and k = 2,
return 4->5->1->2->3->NULL.
"""

from __future__ import print_function
from linked_list import Node


def rotate(l, k):
    n = len(l)
    k %= n
    if k == 0:
        return l
    prev = l.nth(n - k - 1)
    head = prev.next
    prev.next = None
    head.last.next = l
    return head


l = Node.from_iterable([1, 2, 3, 4, 5])
print(rotate(l, 22))
def insertion_sort(l):
    if l is None:
        return l

    sorted_head = l
    unsorted = l.next
    l.next = None

    while unsorted is not None:
        node = sorted_head

        # insert in front of sorted list
        if unsorted.val < node.val:
            sorted_head = unsorted
            unsorted = unsorted.next
            sorted_head.next = node
        else:
            while node.next is not None and node.next.val <= unsorted.val:
                node = node.next
            sorted_tail = node.next
            node.next = unsorted
            unsorted = unsorted.next
            node.next.next = sorted_tail

    return sorted_head


l = Node.from_iterable(reversed(range(10)))
print(insertion_sort(l))
    first_unique = last_unique = None

    node = l
    while node:
        c = 1
        # count duplicates
        while node.next and node.val == node.next.val:
            c += 1
            node = node.next

        # process uniques
        if c == 1:
            if last_unique:
                last_unique.next = node
            else:
                first_unique = node
            last_unique = node

        node = node.next

    return first_unique


for l in (
    Node.from_iterable([1, 2, 3, 4, 4, 5, 5, 6]),
    Node.from_iterable([1, 1, 2, 3, 3, 4, 5]),
    Node.from_iterable([1, 1, 2, 2, 3, 3, 3])
):
    print('Before:', l)
    print('After:', remove_duplicates2(l))
Example #6
0
def merge(l1, l2):
    if l1.val <= l2.val:
        head = tail = l1
        l1 = l1.next
    else:
        head = tail = l2
        l2 = l2.next

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

    if l1:
        tail.next = l1
    else:
        tail.next = l2

    return head


l1 = Node.from_iterable([5, 8, 20])
l2 = Node.from_iterable([4, 11, 15])

print(merge(l1, l2))
Example #7
0
            ind = 1

        if heads[ind] is None:
            heads[ind] = node

        if tails[ind] is not None:
            tails[ind].next = node
        tails[ind] = node
        node = node.next
        tails[ind].next = None
        lens[ind] += 1

    return heads


def qsort(l):
    if l is None or l.next is None:
        return l
    head, tail = partition(l)
    head = qsort(head)
    tail = qsort(tail)
    if head is not None:
        head.last.next = tail
        return head
    else:
        return tail


l = Node.from_iterable([2, 2, 2, 1, 2, 2, 8, 9, 2, 2, 3, 4, 5, 1, 1, 1, 1])
print(qsort(l))
Example #8
0
For example,
Given 1->4->3->2->5->2 and x = 3,
return 1->2->2->4->3->5.
"""

from __future__ import print_function
from linked_list import Node


def partition(l, x):
    heads = [None, None]
    tails = [None, None]

    while l:
        ind = int(l.val >= x)
        if heads[ind] is None:
            heads[ind] = l
        if tails[ind] is not None:
            tails[ind].next = l
        tails[ind] = l
        l = l.next
        tails[ind].next = None

    if tails[0]:
        tails[0].next = heads[1]
    return heads[0] or heads[1]


l = Node.from_iterable([1, 4, 3, 2, 5, 2])
print(partition(l, 3))
Example #9
0
For example,

List 1-->2-->1 is a palindrome.
List 1-->2-->3 is not a palindrome.
"""

from __future__ import print_function
from linked_list import Node


def is_palindrome(l):
    n = len(l)
    head, tail = l.split(n//2 - 1)
    head = head.reverse()
    if n % 2:
        result = head==tail.next
    else:
        result = head==tail
    head = head.reverse()
    head.join(tail)
    return result


for l in (
    Node.from_iterable([1, 2, 3, 2, 1]),
    Node.from_iterable([1, 2, 3, 2, 3]),
    Node.from_iterable([1, 2, 3, 3, 2, 1]),
    Node.from_iterable([1, 2, 3, 3, 2, 3])
):
    print(is_palindrome(l), l)
Example #10
0
    slow = l
    fast = l.next
    if fast is None:
        return

    while fast is not slow:
        # No cycle
        if fast.next is None or fast.next.next is None:
            return
        fast = fast.next.next
        slow = slow.next

    slow = l
    fast = fast.next

    while fast is not slow:
        slow = slow.next
        fast = fast.next

    return slow


# Create linked list with cycle
l = Node.from_iterable([1, 2, 3, 4, 5])
c = Node.from_iterable([6, 7, 8, 9, 10, 11])
l.last.next = c
c.last.next = c

st = cycle_start(l)
print(st.val if st is not None else 'No cycle')
    node = l
    prev = None

    for _ in range(m):
        prev = node
        node = node.next

    head_tail = prev
    rev_tail = node

    for _ in range(n - m + 1):
        if not node:
            break
        next = node.next
        node.next = prev
        prev = node
        node = next

    rev_head = prev
    tail_head = node

    if head_tail is not None:
        head_tail.next = rev_head
    rev_tail.next = tail_head

    return l if m else rev_head


l = Node.from_iterable([1, 2, 3, 4, 5, 6, 7, 8])
print(reverse(l, 2, 4))