zoukankan      html  css  js  c++  java
  • 剑指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

  • 相关阅读:
    自己实现简单Spring Ioc
    java中动态代理的实现
    Token以及签名signature的设计与实现
    Spring boot整合jsp
    spring boot+mybatis整合
    java并发基础(六)--- 活跃性、性能与可伸缩性
    java并发基础(五)--- 线程池的使用
    java并发基础(四)--- 取消与中断
    java并发基础(三)--- 任务执行
    java并发基础(二)
  • 原文地址:https://www.cnblogs.com/eugene0/p/12729114.html
Copyright © 2011-2022 走看看