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))
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))
""" 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))
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))
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))
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))
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)
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))