예제 #1
0
def addTwoNumbers(l1: ListNode, l2: ListNode) -> ListNode:
    #栈1
    stack1 = []
    while l1:
        stack1.append(l1)
        l1 = l1.next
    #栈2
    stack2 = []
    while l2:
        stack2.append(l2)
        l2 = l2.next

    #求和
    carry = 0
    # stack3 = []
    head = None
    while len(stack1) or len(stack2) or carry:
        x = stack1.pop().val if len(stack1) else 0
        y = stack2.pop().val if len(stack2) else 0
        sum = x + y + carry
        # stack3.append(ListNode(sum % 10))
        node = ListNode(sum % 10)
        node.next = head
        head = node
        carry = sum // 10

    #结果栈
    # dummy = ListNode(0)
    # cur = dummy
    # while len(stack3):
    #     cur.next = stack3.pop()
    #     cur = cur.next
    # return dummy.next
    return head
예제 #2
0
def insertionSortList1(head: ListNode) -> ListNode:
    if not head: return head
    dummy = ListNode()
    dummy.next = head
    cur_pre = head
    cur = head.next
    while cur:
        # 直接下一个
        if cur.val >= cur_pre.val:
            cur_pre = cur
            cur = cur.next
        else:  # 一定会有一个比cur大的节点
            h = dummy.next
            greater = None
            while h and h.next != cur:
                if cur.val >= h.val and cur.val <= h.next.val:
                    # 记录先不交换
                    greater = h
                h = h.next

            temp = cur.next

            # 插入cur
            if greater:
                cur.next = greater.next
                greater.next = cur
            else:
                cur.next = dummy.next
                dummy.next = cur

            # 删除cur
            cur = temp
            cur_pre.next = cur

    return dummy.next
예제 #3
0
def sortList2(head: ListNode) -> ListNode:
    """down2up"""
    h, length, intv = head, 0, 1
    while h:
        h, length = h.next, length + 1
    res = ListNode(0)
    res.next = head
    # merge the list in different intv.
    while intv < length:
        pre, h = res, res.next
        while h:
            # get the two merge head `h1`, `h2`
            h1, i = h, intv
            while i and h:
                h, i = h.next, i - 1
            if i: break  # no need to merge because the `h2` is None.
            h2, i = h, intv
            while i and h:
                h, i = h.next, i - 1
            c1, c2 = intv, intv - i  # the `c2`: length of `h2` can be small than the `intv`.
            # merge the `h1` and `h2`.
            while c1 and c2:
                if h1.val < h2.val: pre.next, h1, c1 = h1, h1.next, c1 - 1
                else: pre.next, h2, c2 = h2, h2.next, c2 - 1
                pre = pre.next
            pre.next = h1 if c1 else h2
            while c1 > 0 or c2 > 0:
                pre, c1, c2 = pre.next, c1 - 1, c2 - 1
            pre.next = h
        intv *= 2
    return res.next
예제 #4
0
def reverseKGroup1(head: ListNode, k: int) -> ListNode:
    def reverse(head, tail):
        """翻转一个子链表,并且返回新的头与尾"""
        prev = tail.next
        p = head
        while prev != tail:
            nex = p.next
            p.next = prev
            prev = p
            p = nex
        return tail, head

    dummyNode = ListNode(0)
    dummyNode.next = head
    pre = dummyNode

    while head:
        tail = pre
        # 查看剩余部分长度是否大于等于 k
        for _ in range(k):
            tail = tail.next
            if not tail:
                return dummyNode.next

        nex = tail.next
        head, tail = reverse(head, tail)
        # 把子链表重新接回原链表
        pre.next = head
        tail.next = nex
        pre = tail
        head = tail.next
    return dummyNode.next
예제 #5
0
def insertionSortList2(head: ListNode) -> ListNode:
    if not head: return head
    dummy = ListNode()
    dummy.next = head
    cur_pre = head
    cur = head.next
    while cur:
        # 直接下一个
        if cur.val >= cur_pre.val:
            cur_pre = cur
            cur = cur.next
        else:  # 一定会有一个比cur大的节点
            greater_pre = dummy
            while greater_pre.next.val <= cur.val:
                greater_pre = greater_pre.next

            #这是和官方有出入的地方
            temp = cur.next

            #插入
            cur.next = greater_pre.next
            greater_pre.next = cur

            #下一个
            cur = temp
            cur_pre.next = cur

    return dummy.next
def deleteNode(node: ListNode):
    """
    :type node: ListNode
    :rtype: void Do not return anything, modify node in-place instead.
    """
    #不能删除当前节点,那就交换下一个节点的值然后删除下一个节点
    node.val = node.next.val
    node.next = node.next.next
예제 #7
0
def main():
    node1 = ListNode(1)
    node2 = ListNode(2)
    node1.next = node2
    node3 = ListNode(2)
    node2.next = node3
    node4 = ListNode(1)
    node3.next = node4
    ret = isPalindrome(node1)
    print(ret)
def mergeTwoLists(l1: ListNode, l2: ListNode) -> ListNode:
    if l1 is None:
        return l2
    elif l2 is None:
        return l1
    elif l1.val < l2.val:
        l1.next = mergeTwoLists(l1.next, l2)
        return l1
    else:
        l2.next = mergeTwoLists(l1, l2.next)
        return l2
def deleteDuplicates_skill(head: ListNode) -> ListNode:
    """skill解法:重点已排序,哑结点"""
    dummy = ListNode(0)
    dummy.next = head
    ptr = dummy
    while ptr.next and ptr.next.next:
        if ptr.next.val == ptr.next.next.val:
            ptr.next = ptr.next.next
        else:
            ptr = ptr.next
    return dummy.next
예제 #10
0
def swapPairs2(head: ListNode) -> ListNode:
    dummyHead = ListNode(0)
    dummyHead.next = head
    temp = dummyHead
    while temp.next and temp.next.next:
        node1 = temp.next
        node2 = temp.next.next
        temp.next = node2
        node1.next = node2.next
        node2.next = node1
        temp = node1
    return dummyHead.next
def deleteNode(head: ListNode, val: int) -> ListNode:
    dummy = ListNode(0)
    dummy.next = head
    pre = dummy
    cur = head
    while cur:
        if cur.val == val:
            pre.next = cur.next
            cur = pre.next
        else:
            pre = cur
            cur = cur.next
    return dummy.next
예제 #12
0
def removeElements(head: ListNode, val: int) -> ListNode:
    """模拟题:直接遍历/不用pre节点需要处理end"""
    dummy = ListNode(0)
    dummy.next = head
    pre = dummy
    cur = head
    while cur:
        if cur.val == val:
            pre.next = cur.next
            cur = pre.next
        else:
            pre = cur
            cur = cur.next
    return dummy.next
예제 #13
0
def partition(head: ListNode, x: int) -> ListNode:
    biggerHead = bigger = ListNode()
    smallerHead = smaller = ListNode()
    while head:
        if head.val < x:
            smaller.next = head
            smaller = smaller.next
        else:
            bigger.next = head
            bigger = bigger.next
        head = head.next
    smaller.next = biggerHead.next
    bigger.next = None
    return smallerHead.next
def main():
    node1 = ListNode(4)
    node2 = ListNode(5)
    node1.next = node2
    node3 = ListNode(1)
    node2.next = node3
    node4 = ListNode(9)
    node3.next = node4

    deleteNode(node2)
    head = node1
    while head:
        print(head.val)
        head = head.next
예제 #15
0
def mergeKLists(lists: List[ListNode]) -> ListNode:
    """
    优先队列:
    元组比较:https://leetcode-cn.com/problems/merge-k-sorted-lists/solution/leetcode-23-he-bing-kge-pai-xu-lian-biao-by-powcai/
    vs 自定义比较函数
    """
    def __lt__(self, other):
        return self.val < other.val

    ListNode.__lt__ = __lt__

    import heapq
    heap = []
    for l in lists:
        if l:
            heapq.heappush(heap, l)

    dummy = ListNode(0)
    p = dummy
    while heap:
        node = heapq.heappop(heap)
        p.next = node
        p = p.next
        if node.next:
            heapq.heappush(heap, node.next)

    return dummy.next
def mergeTwoLists1(l1: ListNode, l2: ListNode) -> ListNode:
    """拓展思路:递归实现"""
    dummyNode = ListNode(0)
    result = dummyNode
    while l1 and l2:
        if l1.val > l2.val:
            result.next = l2
            l2 = l2.next
        else:
            result.next = l1
            l1 = l1.next
        result = result.next

    # 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
    result.next = l1 if l1 is not None else l2

    # while l1:
    #     result.next = l1
    #     l1 = l1.next
    #     result = result.next
    #
    # while l2:
    #     result.next = l2
    #     l2 = l2.next
    #     result = result.next

    return dummyNode.next
예제 #17
0
def swapPairs(head: ListNode) -> ListNode:
    """递归"""
    if not head or not head.next:
        return head
    newHead = head.next
    head.next = swapPairs(newHead.next)
    newHead.next = head
    return newHead
def deleteDuplicates(head: ListNode) -> ListNode:
    """解法:重点已排序"""
    dummy = ListNode(0)
    dummy.next = head
    pre, ptr = dummy, head
    while ptr and ptr.next:
        dup = False
        # 找到重复值子链表的最后一个节点
        while ptr and ptr.next and ptr.val == ptr.next.val:
            dup = True
            ptr = ptr.next
        if dup:
            ptr = ptr.next
            pre.next = ptr
        else:
            pre = ptr
            ptr = ptr.next
    return dummy.next
예제 #19
0
def removeZeroSumSublists(head: ListNode) -> ListNode:
    """前缀和+hashmap:sum相同的节点后面会覆盖前面,二次遍历间接删除了sum=0的节点"""
    dummy = ListNode(0)
    dummy.next = head

    sum_map = dict()
    p, sum_value = dummy, 0
    while p:
        sum_value += p.val
        sum_map[sum_value] = p
        p = p.next

    p, sum_value = dummy, 0
    while p:
        sum_value += p.val
        p.next = sum_map[sum_value].next
        p = p.next

    return dummy.next
def deleteDuplicates_naive(head: ListNode) -> ListNode:
    """朴素解法:hash表"""
    if not head or not head.next: return head
    ptr, map = head, {}
    while ptr:
        if ptr.val not in map:
            map[ptr.val] = 0
        else:
            map[ptr.val] += 1
        ptr = ptr.next

    dummy = ListNode(0)
    dummy.next = head
    ptr = dummy
    while ptr.next:
        if map[ptr.next.val] > 0:
            ptr.next = ptr.next.next
        else:
            ptr = ptr.next
    return dummy.next
예제 #21
0
def reverseKGroup(head: ListNode, k: int) -> ListNode:
    """图解k个一组翻转链表:
    一图胜千言:https://leetcode-cn.com/problems/reverse-nodes-in-k-group/solution/tu-jie-kge-yi-zu-fan-zhuan-lian-biao-by-user7208t/
    """
    def reverse(head):
        """翻转链表"""
        pre = None
        cur = head
        while cur:
            temp = cur.next
            cur.next = pre
            pre = cur
            cur = temp
        return pre

    dummyNode = ListNode(0)
    dummyNode.next = head

    # 初始pre/end
    pre = dummyNode
    end = pre

    while end.next:
        for _ in range(k):
            end = end.next
            if not end:
                return dummyNode.next
        #记录start
        start = pre.next
        #记录next
        next = end.next
        #断开k区间的链表
        end.next = None
        #翻转
        pre.next = reverse(start)
        #拼接翻转之后的k区间
        start.next = next
        #重置pre/end
        pre = start
        end = pre
    return dummyNode.next
예제 #22
0
def insertionSortList(head: ListNode) -> ListNode:
    """对于单向链表而言,只有指向后一个节点的指针,因此需要从链表的头节点开始往后遍历链表中的节点,寻找插入位置。"""
    if not head:
        return head

    dummyHead = ListNode(0)
    dummyHead.next = head
    lastSorted = head
    curr = head.next

    while curr:
        if lastSorted.val <= curr.val:
            lastSorted = lastSorted.next
        else:
            prev = dummyHead
            while prev.next.val <= curr.val:
                prev = prev.next
            lastSorted.next = curr.next
            curr.next = prev.next
            prev.next = curr
        curr = lastSorted.next

    return dummyHead.next
예제 #23
0
def addTwoNumbers(l1: ListNode, l2: ListNode) -> ListNode:
    pre = ListNode(0)
    cur = pre

    carry = 0
    while l1 or l2 or carry:
        x = l1.val if l1 else 0
        y = l2.val if l2 else 0
        sum = x + y + carry

        cur.next = ListNode(sum % 10)
        cur = cur.next

        if l1: l1 = l1.next
        if l2: l2 = l2.next

        # 牛逼2 // -> if
        # carry = sum // 10
        carry = 1 if sum > 9 else 0

    # 牛逼1 or carry
    # if carry: cur.next = ListNode(carry)

    return pre.next
예제 #24
0
def swapPairs1(head: ListNode) -> ListNode:
    """迭代"""
    dummyNode = ListNode(0)
    p = dummyNode
    while head:
        cur = head
        if cur.next:
            head = cur.next.next
            cur.next.next = cur
            p.next = cur.next
            p = p.next.next
            p.next = None
        else:
            p.next = cur
            head = None
    return dummyNode.next
예제 #25
0
def sortList(head: ListNode) -> ListNode:
    """快速排序或者归并排序"""
    if not head or not head.next: return head  # termination.
    # cut the LinkedList at the mid index.
    slow, fast = head, head.next
    while fast and fast.next:
        fast, slow = fast.next.next, slow.next
    mid, slow.next = slow.next, None  # save and cut.
    # recursive for cutting.
    left, right = sortList(head), sortList(mid)
    # merge `left` and `right` linked list and return it.
    h = res = ListNode(0)
    while left and right:
        if left.val < right.val:
            h.next, left = left, left.next
        else:
            h.next, right = right, right.next
        h = h.next
    h.next = left if left else right
    return res.next
예제 #26
0
def reverseBetween(head: ListNode, m: int, n: int) -> ListNode:
    ptr, head_ptr = head, None
    while m > 1:
        m -= 1
        n -= 1
        head_ptr = head
        head = head.next

    between_tail = between_ptr = head

    while n > 0:
        n -= 1
        temp = head.next
        head.next = between_ptr
        between_ptr = head
        head = temp

    between_tail.next = head

    if head_ptr is None:
        ptr = between_ptr
    else:
        head_ptr.next = between_ptr
    return ptr
예제 #27
0
def main():
    node1 = ListNode(3)
    node2 = ListNode(2)
    node1.next = node2
    node3 = ListNode(0)
    node2.next = node3
    node4 = ListNode(-4)
    node3.next = node4

    # node5 = ListNode(2)
    # node4.next = node5

    # 链表成环
    node4.next = node2

    #相交节点-4,入环节点2,环长度3
    ret = detectCycle(node1)
    if ret:
        print(ret.val)
    else:
        print(None)
예제 #28
0
def main():
    node1 = ListNode(2)
    node2 = ListNode(4)
    node1.next = node2
    node3 = ListNode(3)
    node2.next = node3
    l1 = node1

    node1 = ListNode(5)
    node2 = ListNode(6)
    node1.next = node2
    node3 = ListNode(4)
    node2.next = node3
    l2 = node1

    ret = addTwoNumbers(l1, l2)
    while (ret):
        print(ret.val)
        ret = ret.next
예제 #29
0
def main():
    node1 = ListNode(3)
    node2 = ListNode(2)
    node1.next = node2
    node3 = ListNode(0)
    node2.next = node3
    node4 = ListNode(-4)
    node3.next = node4
    # node5 = ListNode(2)
    # node4.next = node5
    node4.next = node2
    ret = hasCycle(node1)
    print(ret)
예제 #30
0
def main():
    # 相交部分
    node1 = ListNode(8)
    node2 = ListNode(4)
    node1.next = node2
    node3 = ListNode(5)
    node2.next = node3

    # A
    headA = ListNode(4)
    nodeA1 = ListNode(1)
    headA.next = nodeA1
    nodeA1.next = node1

    # head = headA
    # while head:
    #     print(head.val)
    #     head = head.next

    # B
    headB = ListNode(5)
    nodeB1 = ListNode(0)
    headB.next = nodeB1
    nodeB2 = ListNode(1)
    nodeB1.next = nodeB2
    nodeB2.next = node1

    # head = headB
    # while head:
    #     print(head.val)
    #     head = head.next

    """
    my_list_node = MyListNode()
    my_list_node.addAtTail(4)
    my_list_node.addAtTail(1)
    my_list_node.addAtTail(8)
    my_list_node.addAtTail(4)
    my_list_node.addAtTail(5)

    headA = my_list_node.head

    my_list_node = MyListNode()
    my_list_node.addAtTail(5)
    my_list_node.addAtTail(0)
    my_list_node.addAtTail(1)
    my_list_node.addAtTail(8)
    my_list_node.addAtTail(4)
    my_list_node.addAtTail(5)

    headB = my_list_node.head
    """

    ret = getIntersectionNode(headA, headB)
    if ret:
        print(ret.val)
    else:
        print(None)