Esempio n. 1
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
Esempio n. 2
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)))
Esempio n. 3
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]
Esempio n. 4
0
class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        slow = fast = entry = head
        while fast and fast.next:
            slow, fast = slow.next, fast.next.next
            if slow == fast:
                while slow != entry:
                    slow, entry = slow.next, entry.next
                return entry
        return None


# TESTS
for array, pos in [
    ([3, 2, 0, -4], 1),
    ([1, 2], 0),
    ([1], -1),
]:
    sol = Solution()
    # build the cycle
    head = ListNode.from_array(array)
    p, entry, i = head, None, 0
    while p and p.next:
        if i == pos:
            entry = p
        p, i = p.next, i + 1
    p.next = entry
    actual = sol.detectCycle(head)
    print("The node where cycle begins in", array, "->", actual and actual.val)
    assert actual == entry
Esempio n. 5
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
Esempio n. 6
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
Esempio n. 7
0
            return None
        if not head.next:
            return TreeNode(head.val)

        pslow, slow, fast = None, head, head
        while fast and fast.next:
            pslow, slow = slow, slow.next
            fast = fast.next.next
        pslow.next = None

        return TreeNode(
            slow.val,
            left=self.sortedListToBST(head),
            right=self.sortedListToBST(slow.next),
        )


# TESTS
for array, expected in [
    ([-10, -3, 0, 5, 9], "0,-3,-10,#,#,#,9,5,#,#,#"),
    ([], "#"),
    ([0], "0,#,#"),
    ([1, 3], "3,1,#,#,#"),
    ([1, 2, 3, 4], "3,2,1,#,#,#,4,#,#"),
]:
    sol = Solution()
    actual = TreeNode.serialize(sol.sortedListToBST(
        ListNode.from_array(array)))
    print("Convert sorted list", array, "to BST ->", actual)
    assert actual == expected
Esempio n. 8
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
Esempio 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
Esempio n. 10
0
        Note that the head is guaranteed to be not null, so it contains at least one node.
        """
        self.head = head

    def getRandom(self) -> int:
        """
        Returns a random node's value.
        """
        p, ans, i = self.head.next, self.head.val, 1
        while p:
            if random() < (1 / (1 + i)):
                ans = p.val
            p, i = p.next, i + 1

        return ans


# Your Solution object will be instantiated and called as such:
# obj = Solution(head)
# param_1 = obj.getRandom()
head = ListNode.from_array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
sol = Solution(head)
counter = Counter()
N = 10000
for _ in range(N):
    counter[sol.getRandom()] += 1

for c in counter:
    counter[c] /= N
print(counter)
Esempio n. 11
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))
Esempio n. 12
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
Esempio n. 13
0
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
from local_packages.list import ListNode


class Solution:
    def middleNode(self, head: ListNode) -> ListNode:
        slow, fast = head, head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
        return slow


# TESTS
tests = [
    [[1], 1],
    [[1, 2], 2],
    [[1, 2, 3], 2],
    [[1, 2, 3, 4, 5], 3],
    [[1, 2, 3, 4, 5, 6], 4],
]
for t in tests:
    sol = Solution()
    actual = sol.middleNode(ListNode.from_array(t[0]))
    print("Middle node of", t, "->", actual.val)
    assert actual.val == t[1]
Esempio n. 14
0
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
from local_packages.list import ListNode


class Solution:
    def getDecimalValue(self, head: ListNode) -> int:
        ans, p = 0, head
        while p:
            ans = (ans << 1) + p.val
            p = p.next
        return ans


# TESTS
for array, expected in [
    ([1, 0, 1], 5),
    ([0], 0),
    ([1], 1),
    ([1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0], 18880),
    ([0, 0], 0),
]:
    sol = Solution()
    actual = sol.getDecimalValue(ListNode.from_array(array))
    print("The decimal value of", array, "->", actual)
    assert actual == expected
Esempio n. 15
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
Esempio n. 16
0
        # Length of the input
        length, p = 0, head
        while p is not None:
            p, length = p.next, length + 1
        # Determine the length of each part
        size, rem = length // k, length % k
        ans = [size + 1] * rem + [size] * (k - rem)
        # Split the list
        prev, p = None, head
        for i, sz in enumerate(ans):
            ans[i] = p
            for _ in range(sz):
                prev, p = p, p.next
            if p and prev:
                prev.next = None
        return ans


# TESTS
for array, k, expected in [
    ([1, 2, 3], 5, [[1], [2], [3], [], []]),
    ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3, [[1, 2, 3, 4], [5, 6, 7], [8, 9,
                                                                    10]]),
]:
    sol = Solution()
    actual = list(
        map(ListNode.to_array,
            sol.splitListToParts(ListNode.from_array(array), k)))
    print("Split", array, "into", k, "parts ->", actual)
    assert actual == expected
Esempio n. 17
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
Esempio n. 18
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
Esempio n. 19
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]