链表

逆序打印链表

  • 问题:输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

  • 解决:

    #方法一:
    class Solution:
        def printListFromTailToHead(self, listNode):
            # write code here
            ArrayList = []
            while listNode:
                ArrayList.append(listNode.val)
                listNode = listNode.next
            return ArrayList[::-1]
     #方法二:递归
    # -*- coding:utf-8 -*-
    # class ListNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution:
        def printListFromTailToHead(self, listNode):
            # write code here
            return self.printListFromTailToHead(listNode.next)+ [listNode.val] if listNode else []
    
    

链表前后指针的使用,边界条件检测 (简单)

  • 问题:输入一个链表,输出该链表中倒数第k个结点。

  • 解决:

    # -*- coding:utf-8 -*-
    # class ListNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution:
        def FindKthToTail(self, head, k):
            # write code here
            first , second = head , head
            for _ in range(k):
                if not first: return
                first = first.next
            while first:
                first , second = first.next,second.next
            return second
    

反转链表

  • 问题:输入一个链表,反转链表后,输出新链表的表头。

  • 解决:

    #方法一:定义三个指针,边移动,边翻转
    class Solution:
        # 返回ListNode
        def ReverseList(self, pHead):
            # write code here
            if not pHead or not pHead.next:
                return pHead
            left = pHead
            mid = left.next
            right = mid.next
            while right:
                mid.next = left
                left, mid = mid, right
                right = right.next
            mid.next = left
            pHead.next = None
            pHead = mid
            return pHead
    #简化
    class Solution:
        # 返回ListNode
        def ReverseList(self, pHead):
            # write code here
            if not pHead or not pHead.next:
                return pHead
            p = None
            cur = pHead
            while cur:
                q = cur.next
                cur.next = p
                p, cur = cur,q
            return p
    #方法二:采用头插思想进行翻转
    class Solution:
        # 返回ListNode
        def ReverseList(self, pHead):
            # write code here
            if not pHead or not pHead.next:
                return pHead
            new_head = None
            while pHead:
                #原链表取节点,头插节点到新链表
                p, pHead = pHead, pHead.next
                p.next,new_head = new_head, p
            return new_head
    #方法三:递归
    class Solution:
        # 返回ListNode
        def ReverseList(self, pHead):
            # write code here
            if not pHead or not pHead.next:
                return pHead
            cur = self.ReverseList(pHead.next)
            pHead.next.next = pHead
            pHead.next = None
            return cur
    

合并两个排序的链表

  • 问题:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

  • 解决:

    #方法一:迭代判断
    class Solution:
        # 返回合并后列表
        def Merge(self, pHead1, pHead2):
            # write code here
            pHead = ListNode(-1)
            p = pHead
            while pHead1 and pHead2:
                if pHead1.val <= pHead2.val:
                    p.next = pHead1
                    pHead1 = pHead1.next
                else:
                    p.next = pHead2
                    pHead2 = pHead2.next
                p = p.next
            p.next = pHead1 if pHead1 else pHead2
            return pHead.next
    #方法二:递归
    class Solution:
        # 返回合并后列表
        def Merge(self, pHead1, pHead2):
            # write code here
            if not pHead1:
                return pHead2
            if not pHead2:
                return pHead1
            if pHead1.val <= pHead2.val:
                pHead1.next = self.Merge(pHead1.next, pHead2)
                return pHead1
            else:
                pHead2.next = self.Merge(pHead1, pHead2.next)
                return pHead2
    

删除链表中重复的结点

  • 问题:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

  • 解决:

    #方法一:借助字典和列表
    class Solution:
        def deleteDuplication(self, pHead):
            # write code here
            if not pHead or not pHead.next:
                return pHead
            cache = {}
            arr = []
            p = pHead
            while p:
                k = p.val
                cache[k] = cache.setdefault(k,0)+1
                p = p.next
            for k in cache:
                if cache[k] == 1:
                    arr.append(k)
            new_head = ListNode(0)
            p = new_head
            for i in arr:
                cur = ListNode(i)
                p.next = cur
                p = p.next
            return new_head.next
    #方法二:通过快慢指针的方式限定范围,进而达到去重的效果
    class Solution:
        def deleteDuplication(self, pHead):
            # write code here
            if not pHead or not pHead.next:
                return pHead
            new_head = ListNode(-1)
            p = new_head
            p.next = pHead
            q = pHead
            while q and q.next:
                if p.next.val != q.next.val:
                    p, q = p.next, q.next
                else:
                    while q and q.next and p.next.val == q.next.val:
                        q = q.next
                    p.next = q.next
                    q = q.next
            return new_head.next
    

两个链表的第一个公共结点(简单)

  • 问题:输入两个链表,找出它们的第一个公共结点。

  • 解决:

    class Solution:
        def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
            if not headA or not headB:
                return None
            first = headA
            second = headB
            while first!= second:
                first = first.next if first else headB
                second = second.next if second else headA
            return first
    #空间复杂度:O(1)
    #时间复杂度:O(M+N)
    

复杂链表的复制

  • 问题:复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。

  • 解决:

    #dfs
    class Solution(object):
        def copyRandomList(self, head):
            visited = {}
            def dfs(head):
                if not head:return
                if head in visited:
                    return visited[head]
                clone = Node(head.val,None,None)
                visited[head] = clone
                clone.next = dfs(head.next)
                clone.random = dfs(head.random)
                return clone
            return dfs(head)
    #bfs
    import collections
    class Solution(object):
        def copyRandomList(self, head):
            visited = {}
            def bfs(head):
                if not head: return None
                if head in visited: return head[visited]
                clone = Node(head.val,None,None)
                visited[head] = clone
                queue = collections.deque()
                queue.append(head)
                while queue:
                    q = queue.pop()
                    if q.next and q.next not in visited:
                        visited[q.next] = Node(q.next.val,[],[])
                        queue.append(q.next)
                    if q.random and q.random not in visited:
                        visited[q.random] = Node(q.random.val,[],[])
                        queue.append(q.random)
                    visited[q].next = visited.get(q.next)
                    visited[q].random = visited.get(q.random)
                return clone
            return bfs(head)
    #深拷贝
    import copy
    class Solution(object):
        def copyRandomList(self, head):
            return copy.deepcopy(head)
    
posted @ 2020-07-23 00:23  guguda  阅读(139)  评论(0)    收藏  举报