Example #1
0
    def test_linked_list_cycle(self):
        def addCycle(node, num):
            if num == -1 and not node:
                return
            i = 0
            cur_node = None
            while node.next:
                if i == num:
                    cur_node = node
                i = i + 1
                node = node.next
            node.next = cur_node

        s = Solution()

        # 重载了equal,因此有环时==有问题
        node1 = ListNode.generate([3, 2, 0, -4])
        addCycle(node1, 1)
        self.assertEqual(True, s.hasCycle(node1))

        node2 = ListNode.generate([1, 2])
        addCycle(node2, 0)
        self.assertEqual(True, s.hasCycle(node2))

        node3 = ListNode.generate([1])
        addCycle(node3, -1)
        self.assertEqual(False, s.hasCycle(node3))
Example #2
0
    def kSimilarity1(self, A, B):
        """
        :type A: str
        :type B: str
        :rtype: int
        """
        dummy1, dummy2 = ListNode('s'), ListNode('s')
        cur1, cur2 = dummy1, dummy2

        for c in zip(A, B):
            cur1.next, cur2.next = ListNode(c[0]), ListNode(c[1])
            cur1, cur2 = cur1.next, cur2.next

        cur1, cur2 = dummy1, dummy2
        step = 0
        while cur1.next:
            cur2_1 = cur2
            while cur1.next.val != cur2.next.val:
                cur2 = cur2.next
                step += 1

            if cur2_1 != cur2:
                tmp = cur2.next  # python的多重赋值是否可以简化?
                cur2.next = cur2.next.next
                tmp.next = cur2_1.next
                cur2_1.next = tmp
                cur2 = cur2_1

            cur1, cur2 = cur1.next, cur2.next

        return step
Example #3
0
def swap_pairs(head: ListNode) -> ListNode:
    """
    :type head: ListNode
    :rtype: ListNode
    """
    # Dummy node acts as the prevNode for the head node
    # of the list and hence stores pointer to the head node.
    dummy = ListNode(-1)
    dummy.next = head

    prev_node = dummy

    while head and head.next:
        # Nodes to be swapped
        first_node = head
        second_node = head.next

        # Swapping
        prev_node.next = second_node
        first_node.next = second_node.next
        second_node.next = first_node

        # Reinitializing the head and prev_node for next swap
        prev_node = first_node
        head = first_node.next

    # Return the new head node.
    return dummy.next
    def deleteDuplicates2(self, head: ListNode) -> ListNode:
        # side case
        if not head or not head.next:
            return head

        # dummy node: In case of the LinkedList's head maybe deleted. 'dummy.next' will point to new head when origin head was deleted.
        dummy = ListNode(0)
        dummy.next = head

        # 提前想好要用几个辅助变量。本题很明显需要维护当前节点和当前节点的前一个节点一共俩,直接声明变量赋值,不要乱用head,会导致指向混乱。
        pre = dummy
        cur = head

        # 循环体为cur node节点
        while cur:
            # 碰到cur和cur.next值相等,直接将cur后移,直到不相等
            while cur.next and cur.val == cur.next.val:
                cur = cur.next
            # 以下是cur和cur.next值不相等的情况(此处方法是用if判断,因为假如没有发生过while cur后移操作的话,pre.next应当是指向cur的;而我自己的方法是增加flag变量,学!)
            if pre.next == cur:
                # 没有发生过while cur后移操作:直接将pre后移
                pre = pre.next
            else:
                # 发生过while cur后移操作:维护pre.next链,pre不用动
                pre.next = cur.next
            cur = cur.next
        return dummy.next
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """

        n1 = ListNode(0)  # 优化:先找到小的头节点,可以无需添加dummy节点
        n1.next, n2 = l1, l2
        head = n1

        while n1.next and n2:
            if n1.next.val <= n2.val:
                n1 = n1.next
            else:
                p = n2
                n2 = n2.next
                p.next = n1.next
                n1.next = p
                n1 = n1.next

        if n2:
            n1.next = n2

        return head.next
Example #6
0
def add_two(l1, l2):
    if l1 is None:
        return l2
    elif l2 is None:
        return l1
    else:
        carry = 0
        result = ListNode(0)
        temp = result

        while l1 or l2:
            sum_total = 0
            if l1:
                sum_total = l1.val
                l1 = l1.next
            if l2:
                sum_total += l2.val
                l2 = l2.next
            sum_total += carry
            temp.next = ListNode(sum_total % 10)
            temp = temp.next
            carry = (sum_total >= 10)
        if carry:
            temp.next = ListNode(1)
        temp = result.next
        del result
        return temp
    def test_facebook(self):
        s = Solution()

        self.assertEqual(
            ListNode.generate([1, 1, 2, 3, 4, 4]),
            s.mergeTwoLists(ListNode.generate([1, 2, 4]),
                            ListNode.generate([1, 3, 4])))
Example #8
0
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        def add(n1, n2, c):
            # Return result and carry on.
            r = n1 + n2 + c
            return r % 10, r / 10

        dummy = ListNode(None)
        p, p1, p2 = dummy, l1, l2
        c = 0
        while p1 and p2:
            r, c = add(p1.val, p2.val, c)
            p.next = ListNode(r)
            p, p1, p2 = p.next, p1.next, p2.next

        p1 = p1 if p1 else p2
        while p1:
            r, c = add(p1.val, 0, c)
            p.next = ListNode(r)
            p, p1 = p.next, p1.next

        if c > 0:
            p.next = ListNode(c)
        return dummy.next
Example #9
0
    def test_facebook(self):
        s = Solution()

        self.assertEqual(
            ListNode.generate([7, 0, 8]),
            s.addTwoNumbers(ListNode.generate([2, 4, 3]),
                            ListNode.generate([5, 6, 4])))
Example #10
0
        def merge_sort(head: ListNode,
                       length: int) -> Tuple[ListNode, ListNode]:
            # Sort list for given length, return sorted list and list after length.
            if not head:
                return (None, None)

            if length == 1:
                next_head = head.next
                head.next = None
                return (head, next_head)

            new_head_1, next_to_sort_1 = merge_sort(head, length // 2)
            new_head_2, next_to_sort_2 = merge_sort(next_to_sort_1,
                                                    length // 2 + length % 2)

            # Merge new_head_1 and new_head_2.
            p = dummy = ListNode(0)
            p1, p2 = new_head_1, new_head_2
            while p1 or p2:
                v1 = p1.val if p1 else float('inf')
                v2 = p2.val if p2 else float('inf')
                if v1 <= v2:
                    p.next = p1
                    p1 = p1.next
                else:
                    p.next = p2
                    p2 = p2.next
                p = p.next
            return (dummy.next, next_to_sort_2)
    def addTwoNumbers1(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """

        carry = 0  # 进位标记符
        head = ListNode(0)  # 标记用头节点,最终需要去掉,或在循环体内判断ListNode是否为None
        current = head

        while l1 or l2:
            val = carry
            if l1:
                val += l1.val
                l1 = l1.next
            if l2:
                val += l2.val
                l2 = l2.next

            if val >= 10:  # 参考答案用了divmod除法函数 carry, val = divmod(val, 10)
                val -= 10
                carry = 1
            else:
                carry = 0

            current.next = ListNode(val)
            current = current.next

        if carry == 1:
            current.next = ListNode(carry)

        return head.next
    def test_remove_duplicates_from_sorted_list_ii(self):
        s = Solution()

        self.assertEqual(ListNode.generate([]), s.deleteDuplicates(ListNode.generate([])))
        self.assertEqual(ListNode.generate([1]), s.deleteDuplicates(ListNode.generate([1])))
        self.assertEqual(ListNode.generate([]), s.deleteDuplicates(ListNode.generate([1, 1])))
        self.assertEqual(ListNode.generate([1, 2, 5]), s.deleteDuplicates(ListNode.generate([1, 2, 3, 3, 4, 4, 5])))
        self.assertEqual(ListNode.generate([2, 3]), s.deleteDuplicates(ListNode.generate([1, 1, 1, 2, 3])))
Example #13
0
    def test_19_removeNthFromEnd(self):
        head = ListNode(1)
        head.next = ListNode(2)
        head.next.next = ListNode(3)

        head = self.solution._19_removeNthFromEnd(head, 3)

        self.assertEqual(2, head.val)
        self.assertEqual(3, head.next.val)
    def test_remove_linked_list_elements(self):
        s = Solution()

        self.assertEqual(None,
                         s.removeElements(ListNode.generate([]), 6))
        self.assertEqual(None,
                         s.removeElements(ListNode.generate([6, 6]), 6))
        self.assertEqual(None,
                         s.removeElements(ListNode.generate([6]), 6))
        self.assertEqual(ListNode.generate([1, 2, 3, 4, 5]), s.removeElements(ListNode.generate([1, 2, 6, 3, 4, 5, 6]), 6))
Example #15
0
    def test_24_swapPairs(self):
        head = ListNode(1)
        head.next = ListNode(2)
        head.next.next = ListNode(3)

        head = self.solution._24_swapPairs(head)

        self.assertEqual(2, head.val)
        self.assertEqual(1, head.next.val)
        self.assertEqual(3, head.next.next.val)
    def addTwoNumbers2(self, l1, l2):
        def toint(node):
            return node.val + 10 * toint(node.next) if node else 0

        n = toint(l1) + toint(l2)
        first = last = ListNode(n % 10)
        while n > 9:
            n /= 10
            last.next = last = ListNode(n % 10)
        return first
 def addTwoNumbers1(self, l1, l2):
     addends = l1, l2
     dummy = end = ListNode(0)
     carry = 0
     while addends or carry:
         carry += sum(a.val for a in addends)
         addends = [a.next for a in addends if a.next]
         end.next = end = ListNode(carry % 10)
         carry /= 10
     return dummy.next
    def test_partition_list(self):
        s = Solution()

        # self.assertEqual(ListNode.generate([1, 2, 2, 4, 3, 5]), s.partition(ListNode.generate([1, 4, 3, 2, 5, 2]), 3))
        # self.assertEqual(ListNode.generate([1, 4]), s.partition(ListNode.generate([4, 1]), 3))
        # self.assertEqual(ListNode.generate([]), s.partition(ListNode.generate([]), 3))
        # self.assertEqual(ListNode.generate([1, 2, 3]), s.partition(ListNode.generate([2, 1, 3]), 2))
        # self.assertEqual(ListNode.generate([1]), s.partition(ListNode.generate([1]), 2))
        # self.assertEqual(ListNode.generate([1]), s.partition(ListNode.generate([1]), 0))
        self.assertEqual(ListNode.generate([1, 2, 3]),
                         s.partition(ListNode.generate([3, 1, 2]), 3))
Example #19
0
    def test_linked_list_cycle_ii(self):
        s = Solution()

        list1 = ListNode.generate([1, 2, 3, 4, 5, 6])
        cycle_start = list1.find_by_value(3)
        list1.find_by_value(6).next = cycle_start

        self.assertTrue(cycle_start is s.detectCycle(list1))
        self.assertEqual(None,
                         s.detectCycle(ListNode.generate([1, 2, 3, 4, 5, 6])))
        self.assertEqual(None, s.detectCycle(ListNode.generate([1])))
        self.assertEqual(None, s.detectCycle(ListNode.generate([])))
Example #20
0
    def test_reverse_linked_list(self):
        s = Solution()

        self.assertEqual(ListNode.generate([]),
                         s.reverseList(ListNode.generate([])))
        self.assertEqual(ListNode.generate([5]),
                         s.reverseList(ListNode.generate([5])))
        self.assertEqual(ListNode.generate([5, 1]),
                         s.reverseList(ListNode.generate([1, 5])))
        self.assertEqual(ListNode.generate([3, 2, 1]),
                         s.reverseList(ListNode.generate([1, 2, 3])))
        self.assertEqual(ListNode.generate([5, 4, 3, 2, 1]),
                         s.reverseList(ListNode.generate([1, 2, 3, 4, 5])))
Example #21
0
 def swapPairs(self, head: 'ListNode') -> 'ListNode':
     dummy = ListNode(0)
     dummy.next = head
     cur = dummy
     while cur.next and cur.next.next:
         # pre = cur.next
         # post = cur.next.next
         # cur.next, post.next, pre.next = post, pre, post.next
         cur.next.next.next, cur.next.next, cur.next = cur.next, cur.next.next.next, cur.next.next
         cur = cur.next.next
         # cur.next, cur.next.next.next, cur.next.next = cur.next.next, cur.next, cur.next.next.next
         # cur = cur.next.next
     return dummy.next
 def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
     dummy = ListNode(None)
     dummy.next = head
     f, b = dummy, dummy
     i = 0
     while i < n:
         f = f.next
         i += 1
     while f.next:
         f = f.next
         b = b.next
     b.next = b.next.next
     return dummy.next
Example #23
0
    def test_2_addTwoNumbers(self):
        l1 = ListNode(2)
        l1.next = ListNode(4)
        l1.next.next = ListNode(3)

        l2 = ListNode(5)
        l2.next = ListNode(6)
        l2.next.next = ListNode(4)

        l3 = self.solution._2_addTwoNumbers(l1, l2)

        self.assertEqual(7, l3.val)
        self.assertEqual(0, l3.next.val)
        self.assertEqual(8, l3.next.next.val)
Example #24
0
    def test4(self):
        nums = [1, 2, 3, 4, 5]
        dummy = ListNode()
        node = dummy
        for n in nums:
            next_node = ListNode(val=n)
            node.next = next_node
            node = next_node

        ans = Solution().rotateRight(head=dummy.next, k=10)
        expected = [1, 2, 3, 4, 5]
        actual = ans.vals_as_array()

        self.assertArrayEquals(expected=expected, actual=actual)
Example #25
0
    def removeNthFromEnd(self, head, n):
        dummy = ListNode(-1)
        dummy.next = head
        slow, fast = dummy, dummy

        for i in range(n):
            fast = fast.next

        while fast.next:
            slow, fast = slow.next, fast.next

        slow.next = slow.next.next

        return dummy.next
    def deleteDuplicates1(self, head: ListNode) -> ListNode:
        # maintain a prev to indict last-previous node of current "while"
        prev = ListNode()
        prev.next = head

        # declare a res head
        real_head = ListNode()
        real_head.next = prev

        # side case
        if not head or not head.next:
            return head

        # maintain a flag to indict that if last while go in the "if head.val == head.next.val".
        flag = False

        while head.next:
            if head.val == head.next.val:
                head.next = head.next.next
                flag = True
            else:
                if flag:
                    prev.next = head.next
                    head = prev
                else:
                    prev = head
                head = head.next
                flag = False
        return real_head.next.next
Example #27
0
 def toLinkedList(self, number):
     if number == 0:
         return ListNode(0)
     head = None
     node = None
     while number > 0:
         digit = number % 10
         new = ListNode(digit)
         if head is None:
             head = new
         else:
             node.next = new
         node = new
         number = number // 10
     return head
Example #28
0
 def partition(self, head: ListNode, x: int) -> ListNode:
     p1 = h1 = ListNode(None)
     p2 = h2 = ListNode(None)
     p = head
     while p:
         if p.val < x:
             p1.next = p
             p1 = p1.next
         else:
             p2.next = p
             p2 = p2.next
         p = p.next
     p1.next = h2.next
     p2.next = None
     return h1.next
Example #29
0
 def deleteDuplicates(self, head: ListNode) -> ListNode:
     if not head:
         return head
     dummy = ListNode(None)
     dummy.next = head
     p0, p1 = dummy, dummy.next.next
     while p1:
         if p1.val != p0.next.val:
             p0 = p0.next
         else:
             while p1 and p1.val == p0.next.val:
                 p1 = p1.next
             p0.next = p1
         p1 = p1.next if p1 else None
     return dummy.next
Example #30
0
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        head = ListNode(None)
        r, h1, h2 = head, l1, l2
        carry = 0
        while h1 or h2 or carry:
            v1 = h1.val if h1 else 0
            v2 = h2.val if h2 else 0
            v = v1 + v2 + carry
            carry = v // 10
            r.next = ListNode(v % 10)
            r = r.next
            h1 = h1.next if h1 else None
            h2 = h2.next if h2 else None

        return head.next