链表

返回首页

返回算法分类分析

第一题 Sort List

Sort a linked list in O(n log n) time using constant space complexity.

解法

使用归并排序,将节点分到三个排序中去。注意这里对空链表头的处理。

    # Definition for singly-linked list.
    # class ListNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None

class Solution(object):
    def sortList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if head is None or head.next is None:
            return head

        x = head.val
        h1 = ListNode(None)
        c1 = h1
        h2 = ListNode(None)
        c2 = h2
        h3 = ListNode(None)
        c3 = h3

        c = head
        while c is not None:
            if c.val < x:
                c1.next = c
                c = c.next
                c1 = c1.next
                c1.next = None
            elif c.val > x:
                c2.next = c
                c = c.next
                c2 = c2.next
                c2.next = None
            else:
                c3.next = c
                c = c.next
                c3 = c3.next
                c3.next = None

        h1 = self.sortList(h1.next)
        h2 = self.sortList(h2.next)

        if h1 is None:
            c3.next = h2
            return h3.next
        else:
            tmp = h1
            while tmp.next is not None:
                tmp = tmp.next
            tmp.next = h3.next
            c3.next = h2
            return h1

第二题 Insertion Sort List

Sort a linked list using insertion sort.

解法

插入排序:遍历数组,每遇到一个元素,就插入到已经排好序的部分中合适的位置。

class Solution(object):

def insertionSortList(self, head):

    """

    :type head: ListNode

    :rtype: ListNode

    """

    if head is None or head.next is None:

        return head



    pre_head = ListNode(None)

    pre_head.next = head

    sorted_end, cur = head, head.next

    while cur:

        if cur.val >= sorted_end.val:

            sorted_end, cur = sorted_end.next, cur.next

        else:

            pre, ptr = pre_head, pre_head.next

            while cur.val >= ptr.val:

                pre, ptr = pre.next, ptr.next

            sorted_end.next, pre.next, cur.next, cur = cur.next, cur, ptr, sorted_end.next.next

    return pre_head.next

第三题 Reorder List

Given a singly linked list L: L0→L1→…→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…

You must do this in-place without altering the nodes' values.

For example, Given {1,2,3,4}, reorder it to {1,4,2,3}.

解法

注意这里对解法的拆解,以及对多个返回的处理。

# Definition for singly-linked list.

# class ListNode(object):

#     def __init__(self, x):

#         self.val = x

#         self.next = None



class Solution(object):

def reorderList(self, head):

    """

    :type head: ListNode

    :rtype: void Do not return anything, modify head in-place instead.

    """

    h1, h2 = self.splitToHalves(head)

    h2 = self.reverse(h2)

    self.merge(h1, h2)



def splitToHalves(self, head):

    if head is None or head.next is None:

        return head, None

    ptr = head

    n = 0

    while ptr:

        n += 1

        ptr = ptr.next

    half = (n+1) / 2

    ptr = head

#        print n, half

    while half > 1:

        ptr = ptr.next

        half -= 1



    tmp = ptr.next

    ptr.next = None

    return head, tmp





def reverse(self, head):

    if head is None or head.next is None:

        return head

    p1, p2 = head, head.next

    p1.next = None

    while p2:

        tmp = p2.next

        p2.next = p1

        p1 = p2

        p2 = tmp

    return p1





def merge(self, head1, head2):

    self.printList(head1)

    self.printList(head2)

    if head1 is None:

        return head1

    p1, p2 = head1.next, head2

    h = head1

    while h:

        if p2:

            h.next = p2

        else: 

            break

        p2 = p2.next

        if p1:

            h.next.next = p1

        else:

            break

        p1 = p1.next

        h = h.next.next



def printList(self, head):

    while head:

        print head.val

        head = head.next

第四题 Linked List Cycle

Given a linked list, determine if it has a cycle in it.

Follow up: Can you solve it without using extra space?

解法

如果有环,那么一块一慢的循环一定会有套圈。

# Definition for singly-linked list.

# class ListNode(object):

#     def __init__(self, x):

#         self.val = x

#         self.next = None



class Solution(object):

def hasCycle(self, head):

    """

    :type head: ListNode

    :rtype: bool

    """

    if head is None or head.next is None:

        return False

    fast, slow = head.next, head

    while fast is not None and fast.next is not None and fast != slow:

        fast = fast.next.next

        slow = slow.next



    if fast == slow:

        return True

    else:

        return False

第五题 Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Note: Do not modify the linked list.

解法

数学方法

class Solution(object):
def detectCycle(self, head):
    slow, fast = head, head
    while True:
        if fast == None or fast.next == None: return None
        slow = slow.next; fast = fast.next.next
        if slow == fast: break
    while head != fast:
        head = head.next; fast = fast.next
    return head

第六题 Copy List with Random Pointer

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.

解法

先在原来链表的每一个节点后插入新建的节点,然后复制random,最后拆解出来。

# Definition for singly-linked list with a random pointer.

# class RandomListNode(object):

#     def __init__(self, x):

#         self.label = x

#         self.next = None

#         self.random = None



class Solution(object):

    def copyRandomList(self, head):

    """

    :type head: RandomListNode

    :rtype: RandomListNode

    """

    if not head:

        return head



    ptr = head

    while ptr:

        realNext = ptr.next

        fakeNext = RandomListNode(ptr.label)

        ptr.next = fakeNext

        fakeNext.next = realNext

        ptr = ptr.next.next



    ptr = head

    while ptr:

        if ptr.random:

            ptr.next.random = ptr.random.next

        ptr = ptr.next.next



    ptr = head

    fakeHead = RandomListNode(0)

    fptr = fakeHead

    while ptr:

        fptr.next = ptr.next

        ptr.next = ptr.next.next

        ptr = ptr.next

        fptr = fptr.next



    return fakeHead.next   

第七题 Rotate List

Given a list, rotate the list to the right by k places, where k is non-negative.

For example: Given 1->2->3->4->5->NULL and k = 2, return 4->5->1->2->3->NULL.

解法

注意对 k = k % n 的处理。

class Solution(object):

def rotateRight(self, head, k):

    """

    :type head: ListNode

    :type k: int

    :rtype: ListNode

    """

    ptr = head

    n = 0

    while ptr:

        n += 1

        ptr = ptr.next

    if n == 0 or n == 1:

        return head



    k = k % n



    if k == 0:

        return head



    start = n - k

    ptr = head

    while start > 1:

        ptr = ptr.next

        start -= 1



    newHead = ptr.next

    tail = newHead

    while tail.next:

        tail = tail.next

    tail.next = head

    ptr.next = None

    return newHead

第八题 Remove Duplicates from Sorted List

Given a sorted linked list, delete all duplicates such that each element appear only once.

For example, Given 1->1->2, return 1->2. Given 1->1->2->3->3, return 1->2->3.

解法

# Definition for singly-linked list.

# class ListNode(object):

#     def __init__(self, x):

#         self.val = x

#         self.next = None



class Solution(object):

def deleteDuplicates(self, head):

    """

    :type head: ListNode

    :rtype: ListNode

    """

    if not head or not head.next:

        return head



    ptr1, ptr2 = head, head.next

    while ptr2:

        while ptr2.val == ptr1.val and ptr2.next is not None:

            ptr2 = ptr2.next

        if ptr2.next is None and ptr2.val == ptr1.val:

            ptr1.next = None

            return head

        elif ptr2.next is None and ptr2.val != ptr1.val:

            ptr1.next = ptr2

            return head

        else:

            ptr1.next = ptr2

            ptr1 = ptr2

            ptr2 = ptr2.next

第九题 Remove Duplicates from Sorted List II

Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.

For example, Given 1->2->3->3->4->4->5, return 1->2->5. Given 1->1->1->2->3, return 2->3.

解法

这里又一次使用了自己构造虚拟链表头的方法,极大地简化的问题的解法。

class Solution(object):

def deleteDuplicates(self, head):

    """

    :type head: ListNode

    :rtype: ListNode

    """

    if head is None or head.next is None:

        return head



    dummy = ListNode(-999999)

    dummy.next = head



    cur = head

    prev = dummy

    dup = False



    while cur.next is not None:

        if cur.val == cur.next.val:

            cur = cur.next

            dup = True

        else:

            if dup:

                prev.next = cur.next

                cur = cur.next

                dup = False

            else:

                prev = cur

                cur = cur.next

    if dup:

        prev.next = None

    return dummy.next

第十题 Partition List

Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.

You should preserve the original relative order of the nodes in each of the two partitions.

For example, Given 1->4->3->2->5->2 and x = 3, return 1->2->2->4->3->5.

解法

同样使用虚拟表头的方法。

class Solution(object):

def partition(self, head, x):

    """

    :type head: ListNode

    :type x: int

    :rtype: ListNode

    """

    if head is None or head.next is None:

        return head



    less = ListNode(0)

    lessPtr = less

    greater = ListNode(0)

    greaterPtr = greater

    ptr = head

    while ptr:

        if ptr.val < x:

            lessPtr.next = ptr

            ptr = ptr.next

            lessPtr = lessPtr.next

            lessPtr.next = None

        else:

            greaterPtr.next = ptr

            ptr = ptr.next

            greaterPtr = greaterPtr.next

            greaterPtr.next = None



    lessPtr.next = greater.next

    return less.next

第十一题 Swap Nodes in Pairs

Given a linked list, swap every two adjacent nodes and return its head.

For example, Given 1->2->3->4, you should return the list as 2->1->4->3.

Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.

解法

又是一个使用虚拟头的例子,注意在设置这类的情况下,最好标志位ptr自己站在已经完成好处理的段的尾节点上。

class Solution(object):

def swapPairs(self, head):

    """

    :type head: ListNode

    :rtype: ListNode

    """

    dummy = ListNode(0)

    dummy.next = head

    ptr = dummy

    while ptr.next is not None and ptr.next.next is not None:

        tmp = ptr.next.next

        ptr.next.next = tmp.next

        tmp.next = ptr.next

        ptr.next = tmp

        ptr = ptr.next.next

    return dummy.next

第十二题 Merge Two Sorted Lists

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

解法

class Solution(object):

def mergeTwoLists(self, l1, l2):

    """

    :type l1: ListNode

    :type l2: ListNode

    :rtype: ListNode

    """

    dummy = ListNode(0)

    ptr = dummy

    while l1 is not None and l2 is not None:

        if l1.val < l2.val:

            ptr.next = l1

            l1 = l1.next

            ptr = ptr.next

            ptr.next = None

        else:

            ptr.next = l2

            l2 = l2.next

            ptr = ptr.next

            ptr.next = None

    if l1 is None:

        ptr.next = l2

        return dummy.next

    else:

        ptr.next = l1

        return dummy.next

第十三题 Merge k Sorted Lists

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

解法

这里使用了heap,注意python中heap的用法。另外这里可以用虚拟表头来简化代码。

from heapq import heapify, heappop, heappush

class Solution(object):

def mergeKLists(self, lists):

    """

    :type lists: List[ListNode]

    :rtype: ListNode

    """



    h = [(l.val, l) for l in lists if l]

    heapify(h)

    new_head = current = None

    while len(h):

        val, node = heappop(h)

        if node.next:

            heappush(h, (node.next.val, node.next))

        if not new_head:

            current = new_head = node

        else:

            current.next = node

            current = node

            node.next = None

    return new_head

第十四题 Reverse Nodes in k-Group

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.

You may not alter the values in the nodes, only nodes itself may be changed.

Only constant memory is allowed.

For example, Given this linked list: 1->2->3->4->5

For k = 2, you should return: 2->1->4->3->5

For k = 3, you should return: 3->2->1->4->5

解法

class Solution(object):



def reverse(self, head, n):

    assert n > 0

    assert head is not None



    tail = head

    current = head.next

    length = n

    n -= 1



    while n > 0 and current is not None:

        next = current.next

        current.next = head

        head = current

        current = next

        n -= 1



    tail.next = current

    return (head, tail, length - n)





def reverseKGroup(self, head, k):

    """

    :type head: ListNode

    :type k: int

    :rtype: ListNode

    """

    dummy = ListNode(None)

    dummy.next = head

    current = dummy



    while current is not None and current.next is not None:

        sublist = self.reverse(current.next, k)

        if sublist[2] != k:

            sublist = self.reverse(sublist[0],k)

        current.next= sublist[0]

        current = sublist[1]



    return dummy.next

第十五题 Remove Nth Node From End of List

Given a linked list, remove the nth node from the end of list and return its head.

For example,

Given linked list: 1->2->3->4->5, and n = 2.

After removing the second node from the end, the linked list becomes 1->2->3->5.

Note:

Given n will always be valid.

Try to do this in one pass.

解法

这里也用到了虚拟头。


class Solution(object):

def removeNthFromEnd(self, head, n):

    """

    :type head: ListNode

    :type n: int

    :rtype: ListNode

    """

    dummy = ListNode(0)

    dummy.next = head

    tmp = dummy

    ptr = dummy

    while n > 0:

        ptr = ptr.next

        n -= 1

    while ptr.next:

        ptr = ptr.next

        tmp = tmp.next



    tmp.next = tmp.next.next

    return dummy.next

第十六题 Reverse Linked List II

Reverse a linked list from position m to n. Do it in-place and in one-pass.

For example: Given 1->2->3->4->5->NULL, m = 2 and n = 4,

return 1->4->3->2->5->NULL.

Note: Given m, n satisfy the following condition: 1 ≤ m ≤ n ≤ length of list.

解法

class Solution(object):



def reverse(self, head, n):

    assert n > 0

    assert head is not None



    tail = head

    current = head.next

    length = n

    n -= 1



    while n > 0 and current is not None:

        next = current.next

        current.next = head

        head = current

        current = next

        n -= 1



    tail.next = current

    return (head, tail)



def reverseBetween(self, head, m, n):

    """

    :type head: ListNode

    :type m: int

    :type n: int

    :rtype: ListNode

    """

    dummy = ListNode(0)

    dummy.next = head

    ptr = dummy

    mm = m

    while mm > 1:

        ptr = ptr.next

        mm -= 1



    nn = n

    end = dummy

    while nn >= 0:

        end = end.next

        nn -= 1



    length = n - m + 1

    re = self.reverse(ptr.next, length)

    ptr.next, re[1].next = re[0], end



    return dummy.next