def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
     if l1 is None:
         return l2
     elif l2 is None:
         return l1
     elif l1.val < l2.val:
         l1.next = self.mergeTwoLists(l1.next, l2)
         return l1
     else:
         l2.next = self.mergeTwoLists(l1, l2.next)
         return l2
    def reverseList(self, head: ListNode) -> ListNode:
        if head is None:
            return None

        prev = cur = ListNode(head.val)
        while head.next:
            prev = ListNode(head.next.val)
            prev.next = cur

            cur = prev
            head = head.next

        return prev
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        dummy = ListNode()
        dummy.next = head

        # use two pointers
        first = dummy
        second = dummy

        for _ in range(n + 1):
            first = first.next

        while first:
            first = first.next
            second = second.next
        second.next = second.next.next
        return dummy.next
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        dummy = ListNode()
        dummy.next = head

        # count size
        size = 0
        node = head
        while node:
            size += 1
            node = node.next

        # find target's prev node and unlink target node
        prev_node = dummy
        for _ in range(size - n):
            prev_node = prev_node.next
        prev_node.next = prev_node.next.next

        return dummy.next
    def reverseList(self, head: ListNode) -> ListNode:
        if head is None or head.next is None:
            return head

        p = self.reverseList(head.next)
        head.next.next = head
        head.next = None

        return p
    def removeElements(self, head: ListNode, val: int) -> ListNode:
        curr = dummy = ListNode()
        dummy.next = head
        while curr.next:
            if curr.next.val == val:
                curr.next = curr.next.next
                continue

            curr = curr.next

        return dummy.next
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        n1 = l1
        n2 = l2
        merged = head = ListNode()
        while n1 and n2:
            if n1.val < n2.val:
                merged.next = ListNode(n1.val)
                n1 = n1.next
            else:
                merged.next = ListNode(n2.val)
                n2 = n2.next
            merged = merged.next

        while n1:
            merged.next = ListNode(n1.val)
            merged = merged.next
            n1 = n1.next

        while n2:
            merged.next = ListNode(n2.val)
            merged = merged.next
            n2 = n2.next

        return head.next
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        prehead = ListNode(-1)

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

        prev.next = l1 if l1 is not None else l2

        return prehead.next