Ejemplo n.º 1
0
        while p.next:
            length += 1
            p = p.next
        k = length - k % length
        if k == length:  # corner case
            return head
        p.next = head  # circle the list
        # move length - k steps for break point
        while k > 0:
            k -= 1
            p = p.next
        ans_head = p.next
        p.next = None
        return ans_head


# TESTS
tests = [
    ([], 4, []),
    ([1, 2, 3], 0, [1, 2, 3]),
    ([1, 2], 2, [1, 2]),
    ([1], 99, [1]),
    ([1, 2, 3, 4, 5], 2, [4, 5, 1, 2, 3]),
    ([0, 1, 2], 4, [2, 0, 1]),
]
for array, k, expected in tests:
    sol = Solution()
    actual = ListNode.to_array(sol.rotateRight(ListNode.from_array(array), k))
    print("Rotate", array, "right by", k, "places ->", actual)
    assert actual == expected
Ejemplo n.º 2
0
class Solution:
    def insertionSortList(self, head: ListNode) -> ListNode:
        prev = sentinal = ListNode()
        while head:
            nxt = head.next
            # Optimization: search from begining
            # only when head is supposed in front of last insert point
            if head.val <= prev.val:
                prev = sentinal
            while prev.next and prev.next.val < head.val:
                prev = prev.next
            head.next = prev.next
            prev.next = head
            head = nxt
        return sentinal.next


# TESTS
for array, expected in [
    ([], []),
    ([3], [3]),
    ([4, 2, 1, 3], [1, 2, 3, 4]),
    ([-1, 5, 3, 4, 0], [-1, 0, 3, 4, 5]),
]:
    sol = Solution()
    actual = ListNode.to_array(
        sol.insertionSortList(ListNode.from_array(array)))
    print("Sort", array, "->", actual)
    assert actual == expected
Ejemplo n.º 3
0
            return head
        dummy = ListNode(0, head)

        pre, i = dummy, 0
        while i < left - 1:
            i, pre = i + 1, pre.next

        start = pre.next
        then = start.next

        while i < right - 1:
            start.next = then.next
            then.next = pre.next
            pre.next = then
            then = start.next
            i += 1

        return dummy.next


# TESTS
for array, left, right, expected in [
    ([1, 2, 3, 4, 5], 2, 4, [1, 4, 3, 2, 5]),
    ([5], 1, 1, [5]),
]:
    sol = Solution()
    actual = ListNode.to_array(
        sol.reverseBetween(ListNode.from_array(array), left, right))
    print("Reverse", array, "between", left, "and", right, "->", actual)
    assert actual == expected
Ejemplo n.º 4
0
            prev.next = p.next
            q = p.next.next
            p.next.next, p.next = p, q
            prev, p = p, q
        return dummy.next

    def swapPairsRec(self, head: ListNode) -> ListNode:
        if not head or not head.next:
            return head
        n = head.next
        head.next = self.swapPairsRec(n.next)
        n.next = head
        return n


# TESTS
for t, expected in [
    ([], []),
    ([1], [1]),
    ([1, 2], [2, 1]),
    ([1, 2, 3], [2, 1, 3]),
    ([1, 2, 3, 4], [2, 1, 4, 3]),
    ([1, 2, 3, 4, 5, 6, 7], [2, 1, 4, 3, 6, 5, 7]),
    ([1, 2, 3, 4, 5, 6, 7, 8], [2, 1, 4, 3, 6, 5, 8, 7]),
]:
    sol = Solution()
    actual = ListNode.to_array(sol.swapPairs(ListNode.from_array(t)))
    print("Swap pairs", t, "->", actual)
    assert actual == expected
    assert expected == ListNode.to_array(sol.swapPairsRec(ListNode.from_array(t)))
Ejemplo n.º 5
0
        dummy, carry = ListNode(), 0
        for e1, e2 in zip_longest(s1[::-1], s2[::-1]):
            s = carry
            if e1:
                s += e1
            if e2:
                s += e2
            carry = s // 10
            dummy.next = ListNode(s % 10, dummy.next)
        if carry == 1:
            dummy.next = ListNode(1, dummy.next)
        return dummy.next


# TESTS
for a1, a2, expected in [
    ([], [], []),
    ([1], [], [1]),
    ([3], [5], [8]),
    ([6], [9], [1, 5]),
    ([6, 5], [9, 0, 2], [9, 6, 7]),
    ([6, 5], [9, 4, 9], [1, 0, 1, 4]),
    ([7, 2, 4, 3], [5, 6, 4], [7, 8, 0, 7]),
    ([9, 9, 9], [1], [1, 0, 0, 0]),
]:
    sol = Solution()
    actual = ListNode.to_array(
        sol.addTwoNumbers(ListNode.from_array(a1), ListNode.from_array(a2)))
    print("Add", a1, "+", a2, "->", actual)
    assert actual == expected
Ejemplo n.º 6
0
    # produce two sub lists and concatnate them
    def oddEvenListV2(self, head: ListNode) -> ListNode:
        if not head:
            return None
        pod, pev, evhead = head, head.next, head.next
        while pod.next and pev.next:
            pod.next = pev.next
            pev.next = pod.next.next
            pod = pod.next
            pev = pev.next
        pod.next = evhead
        return head


# TESTS
tests = [
    ([], []),
    ([1], [1]),
    ([1, 2], [1, 2]),
    ([1, 2, 3, 4, 5], [1, 3, 5, 2, 4]),
    ([1, 2, 3, 4, 5, 6], [1, 3, 5, 2, 4, 6]),
    ([2, 1, 3, 5, 6, 4, 7], [2, 3, 6, 7, 1, 5, 4]),
]
for t in tests:
    sol = Solution()
    actual1 = ListNode.to_array(sol.oddEvenListV1(ListNode.from_array(t[0])))
    actual2 = ListNode.to_array(sol.oddEvenListV2(ListNode.from_array(t[0])))
    print("Odd even linked list of", t[0], "->", t[1])
    assert actual1 == t[1] and actual2 == t[1]
Ejemplo n.º 7
0
        if not head or not head.next:
            return head
        pre, slow, fast = None, head, head
        while fast and fast.next:
            pre, slow, fast = slow, slow.next, fast.next.next
        pre.next = None
        return self.merge(self.sortList(head), self.sortList(slow))

    def merge(self, l1: ListNode, l2: ListNode) -> ListNode:
        sentinal = p = ListNode()
        while l1 and l2:
            if l1.val <= l2.val:
                p.next, p, l1 = l1, l1, l1.next
            else:
                p.next, p, l2 = l2, l2, l2.next
        p.next = l1 or l2
        return sentinal.next


# TESTS
tests = [
    ([4, 2, 1, 3], [1, 2, 3, 4]),
    ([-1, 5, 3, 4, 0], [-1, 0, 3, 4, 5]),
    ([], []),
    ([7], [7]),
]
for nums, expected in tests:
    sol = Solution()
    actual = ListNode.to_array(sol.sortList(ListNode.from_array(nums)))
    assert actual == expected
Ejemplo n.º 8
0
class Solution:
    def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
        dummy = jump = ListNode(0)
        dummy.next = l = r = head
        while True:
            count = 0
            while r and count < k:  # use r to locate the range
                r, count = r.next, count + 1
            if count == k:
                cur, pre = l, r
                for _ in range(k):
                    cur.next, cur, pre = pre, cur.next, cur
                jump.next, jump, l = pre, l, r  # connect two k-groups
            else:
                return dummy.next


# TESTS
for array, k, expected in [
    ([1, 2, 3, 4, 5], 2, [2, 1, 4, 3, 5]),
    ([1, 2, 3, 4, 5], 3, [3, 2, 1, 4, 5]),
    ([1, 2, 3, 4, 5], 1, [1, 2, 3, 4, 5]),
    ([1], 1, [1]),
]:
    sol = Solution()
    actual = ListNode.to_array(sol.reverseKGroup(ListNode.from_array(array),
                                                 k))
    print("Reverse nodes in k-group", array, "->", actual)
    assert actual == expected
Ejemplo n.º 9
0
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        sentinel = ListNode(0)
        p = sentinel
        while l1 and l2:
            if l1.val < l2.val:
                p.next = l1
                l1 = l1.next
            else:
                p.next = l2
                l2 = l2.next
            p = p.next
        p.next = l1 if l1 else l2
        return sentinel.next


# TESTS
for l1, l2, expected in [
    ([], [], []),
    ([1], [2], [1, 2]),
    ([], [0], [0]),
    ([1, 1, 1], [1, 1, 2], [1, 1, 1, 1, 1, 2]),
    ([1, 2, 4], [1, 3, 4], [1, 1, 2, 3, 4, 4]),
    ([1, 3, 9], [2, 4, 6, 8, 10], [1, 2, 3, 4, 6, 8, 9, 10]),
]:
    sol = Solution()
    actual = ListNode.to_array(
        sol.mergeTwoLists(ListNode.from_array(l1), ListNode.from_array(l2)))
    print("Merge", l1, "and", l2, "->", actual)
    assert actual == expected
Ejemplo n.º 10
0

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeElements(self, head: ListNode, val: int) -> ListNode:
        sentinel = ListNode(val + 1, head)
        p = sentinel
        while p and p.next:
            if p.next.val == val:
                p.next = p.next.next
            else:
                p = p.next
        return sentinel.next


# TESTS
tests = [
    ([], 1, []),
    ([1], 2, [1]),
    ([1, 1], 1, []),
    ([6, 1, 2, 3, 6, 4, 5, 6], 6, [1, 2, 3, 4, 5]),
]
for t in tests:
    sol = Solution()
    actual = sol.removeElements(ListNode.from_array(t[0]), t[1])
    print("Remove elements from", t[0], "->", ListNode.to_array(actual))
Ejemplo n.º 11
0
from local_packages.list import ListNode


class Solution:
    def partition(self, head: ListNode, x: int) -> ListNode:
        p1 = h1 = ListNode(-101)
        p2 = h2 = ListNode(101)
        while head:
            if head.val < x:
                p1.next = head
                p1 = p1.next
            else:
                p2.next = head
                p2 = p2.next
            head = head.next
        p1.next, p2.next = h2.next, None
        return h1.next


# TESTS
for array, x, expected in [
    ([], 3, []),
    ([1, 4, 3, 2, 5, 2], 3, [1, 2, 2, 4, 3, 5]),
    ([2, 1], 2, [1, 2]),
    ([1, 4, 3, 0, 2, 5, 2], 3, [1, 0, 2, 2, 4, 3, 5]),
]:
    sol = Solution()
    actual = ListNode.to_array(sol.partition(ListNode.from_array(array), x))
    print("Partition", array, "->", actual)
    assert actual == expected
Ejemplo n.º 12
0
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        sentinal = ListNode(0, next=head)
        p, was_dup = sentinal, False
        while p and p.next:
            if p.next.next:
                is_dup = p.next.val == p.next.next.val
                if is_dup or was_dup:
                    p.next = p.next.next  # delete p.next but not iterate
                else:
                    p = p.next
                was_dup = is_dup
            else:
                if was_dup:
                    p.next = None  # delete the last duplicate
                p = p.next
        return sentinal.next


# TESTS
for given, expected in [
    ([], []),
    ([1, 2, 3, 3, 4, 4, 5], [1, 2, 5]),
    ([1, 1, 1, 2, 3], [2, 3]),
    ([1, 4, 4, 4], [1]),
]:
    sol = Solution()
    actual = ListNode.to_array(sol.deleteDuplicates(
        ListNode.from_array(given)))
    print("Delete duplicates from", given, "->", actual)
    assert actual == expected
Ejemplo n.º 13
0
        while first and first.next:
            first, second = first.next.next, second.next
        mid, p = second.next, second.next
        second.next = None
        # Reverse the second half
        while p and p.next:
            nxt = p.next
            p.next = nxt.next
            nxt.next = mid
            mid = nxt
        # Interweave
        p1, p2 = head, mid
        while p1 and p2:
            p1nxt, p2nxt = p1.next, p2.next
            p1.next, p2.next = p2, p1nxt
            p1, p2 = p1nxt, p2nxt


# TEST
tests = [
    ([1, 2, 3, 4], [1, 4, 2, 3]),
    ([1, 2, 3, 4, 5], [1, 5, 2, 4, 3]),
    ([0, 1, 2, 3, 4, 5], [0, 5, 1, 4, 2, 3]),
]
for t in tests:
    sol = Solution()
    head = ListNode.from_array(t[0])
    sol.reorderList(head)
    print("Reorder list ->", ListNode.to_array(head))
    assert ListNode.to_array(head) == t[1]