剑指Offer数据结构之链表[Python版]

面试题003 从尾到头打印单链表

题目描述:
输入一个链表,按链表从尾到头的顺序返回一个ArrayList。
解题思路:链表的每个元素由两部分组成,元素值和下一个元素的地址,输入一个链表,开始指针指向第一个节点,操作完一个节点接着将指针指向第二个节点,将元素值保存在列表中,逆序操作是list[::-1]
代码:

class Solution:
    # 返回从尾部到头部的列表值序列,例如[1,2,3]
    def printListFromTailToHead(self, listNode):
        res = []
        while listNode:
            res.append(listNode.val)
            listNode = listNode.next
        return res[::-1]

面试题014 链表中倒数第K个节点

解题思路1 将链表遍历一遍,返回倒数第K个节点
代码

class Solution:
    def FindKthToTail(self, head, k):
        # write code here
        l = []
        while head != None:
            l.append(head)
            head = head.next
        if k > len(l) or k < 1:
            return
        return l[-k]

解题思路2:倒数第k,就是正数第n-k+1(从1开始),设置两个指针p1 p2,p1先走k-1步,然后p1 p2再一起走 p1为到达最后一个时,p2位于链表第n-k+1节点,也就是倒数第k个节点
代码

class Solution:
    def FindKthToTail(self, head, k):
        # write code here
        if head==None or k <= 0:
            return None
        p1 = head
        p2 = head
        while k > 1:
            if p1.next != None:
                p1 = p1.next
                k -= 1
            else:
                return None
        while p1.next != None:
            p1 = p1.next
            p2 = p2.next
        return p2

面试题015 反转链表

解题思路:维护三个指针,pre cur cur.next 需要考虑空链表和一个结点的链表
代码:

class Solution:
   
    def ReverseList(self, pHead):
        # write code here
        if pHead==None or pHead.next==None:
            return pHead
        pre = None
        cur = pHead
        while cur!=None:
            tmp = cur.next
            cur.next = pre
            pre = cur
            cur = tmp
        return pre

面试题016 合并两个排序的链表

解题思路1 递归
代码

class Solution:
    # 返回合并后列表
    def Merge(self, pHead1, pHead2):
        # write code here
        if pHead1 == None:
            return pHead2
        if pHead2 == None:
            return pHead1
         
        if pHead1.val<=pHead2.val:
            pHead1.next = Solution.Merge(self,pHead1.next,pHead2)
            return pHead1
        else:
            pHead2.next = Solution.Merge(self,pHead1,pHead2.next)
            return pHead2

解题思路2 非递归
代码

class Solution:
    # 返回合并后列表
    def Merge(self, pHead1, pHead2):
        # write code here
        #初始化
        tmp = ListNode(0)
        pHead = tmp        
        while pHead1 and pHead2:
            if pHead1.val < pHead2.val:
                tmp.next = pHead1
                pHead1 = pHead1.next
            else:
                tmp.next = pHead2
                pHead2 = pHead2.next
            tmp = tmp.next
        if not pHead1:
            tmp.next = pHead2
        if not pHead2:
            tmp.next = pHead1
        return pHead.next

面试题025 复杂链表的复制

题目描述:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
解题思路:递归法
代码

class Solution:
    def Clone(self, head):
        if not head: return
        newNode = RandomListNode(head.label)
        newNode.random = head.random
        newNode.next = self.Clone(head.next)
        return newNode

面试题036 两个链表的第一个公共结点

题目描述:输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
解题思路:先将链表1的所有结点放在list中,然后遍历链表2,如果有公共结点,则链表2的一个结点在list中出现
代码

class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        # write code here
        list1 = []
        list2 = []
        node1 = pHead1
        node2 = pHead2
        while node1:
            list1.append(node1.val)
            node1 = node1.next
        while node2:
            if node2.val in list1:
                return node2
            else:
                node2 = node2.next

面试题055 链表中环的入口结点

题目描述:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
解题思路:通过建立一个列表,然后将链表中第一次出现的加入到列表中,当遇到已经出现过的节点,那么那个节点就是环的入口
代码

class Solution:
    def EntryNodeOfLoop(self, pHead):
        # write code here
        if pHead==None:
            return None
        list1=[]
        while(pHead):
            if pHead in list1:
                return pHead
            list1.append(pHead)
            pHead=pHead.next

面试题 删除排序链表中的重复元素

题目描述:给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
示例 1:
输入: 1->1->2
输出: 1->2
解题思路:一次遍历,用a和b两个指针,两个指针初始位置都指向链表头部,然后b指针不断往前走,如果a指针和b指针的元素相等则啥都不做;如果a指针和b指针的元素不等,则a指针也往前走一位,并将b指针的值赋给a指针。

代码

class Solution(object):
    def deleteDuplicates(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not (head and head.next):
            return head
        i,j = head, head
        while j:
            if i.val != j.val:
                i = i.next
                i.val = j.val
            j = j.next
        i.next = None
        return head

面试题056 删除排序链表中的重复元素

题目描述:给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
示例 :
输入: 1->2->3->3->4->4->5
输出: 1->2->5
解题思路:按规律循环遍历,三个指针,记录上一个不重复的节点pPre,当前节点pThis,下个节点pNext。在遍历pThis时如果当前节点pThis的值跟后面的几个节点数值相同,需要找到下个不同的节点,删除重复节点,更新pPre和pThis;如果pThis的值跟后面的节点数值不同,直接更新pPre和pThis。如果pHead就是重复的,需要更新pHead。
代码

class Solution(object):
    def deleteDuplicates(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if head == None or head.next == None:
            return head
        pPre = None
        pThis = head
        pNext = None
        while(pThis):
            if(pThis.next and pThis.next.val == pThis.val):
                pNext = pThis.next
                while(pNext.next and pNext.next.val == pThis.val):
                    pNext = pNext.next
                if(pThis == head):
                    head = pNext.next
                else:
                    pPre.next = pNext.next
                pThis = pNext.next
            else:
                pPre = pThis
                pThis = pThis.next
        return head

From 剑指Offer

class Solution:
    def deleteDuplication(self, pHead):
        # write code here
        result=ListNode(0)
        res=result
        result.next=pHead
        tmp=pHead
        while tmp and tmp.next:
            if tmp.val==tmp.next.val:
                while tmp.next and tmp.val==tmp.next.val:
                    tmp=tmp.next
            else:
                res.next=tmp
                res=res.next
            tmp=tmp.next
        res.next=tmp
        return result.next

参考题目地址:剑指Offer编程题 牛客网
面试必刷-《剑指offer》刷题小结
https://github.com/nlpjoe/Coding4Interviews

posted @ 2020-05-13 00:21  Christine_7  阅读(241)  评论(0编辑  收藏  举报