剑指offer——链表题目集合(Python)

链表的题,感觉会了链表的操作应该是没什么问题.链表的访问都是基于while.

1 链表中倒数第k个节点

题目描述

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

解题思路:两种方法,第一种是先访问一便链表,知道链表长度n,然后走到n-k的结点就是.第二个就是先让一个走k步,然后2个一起走,第一个走到头,返回第二个当前所在的结点.由于时间复杂度都一样,就第一种.

class Solution:
    def FindKthToTail(self, head, k):
        if not head:
            return None
        n=1
        t = head
        while(head.next):
            head = head.next
            n=n+1
        if k>n:
            return None
        i=0
        while(i<n-k):
            t = t.next
            i = i+1
        return t

2 反转链表

题目描述

输入一个链表,反转链表后,输出新链表的表头。

解题思路:定义3个变量,pre,cur,nex分别表示上一个节点,当前节点,和下一个节点.pre初始值为None,一共4步:先赋值nex保留下一个节点-->更改cur指针指向pre-->更新pre为当前节点cur-->更新cur为nex. 注意,最好返回的是新的链表的头节点,也就是原来链表的尾结点,具体代码如下:

class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        if not pHead:
            return None

        pre = None
        while(pHead):
            nex = pHead.next 
            pHead.next = pre
            pre = pHead
            pHead = nex
        
        return pre

3 合并2个排序的链表

题目描述

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

解题思路:此法有递归和非递归方法,建议2种都要会

1 递归版本

class Solution:
    # 返回合并后列表
    def Merge(self, pHead1, pHead2):
        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

2 非递归版本

class Solution:
    # 返回合并后列表
    def __init__(self):
        self.p = None
    def Merge(self, pHead1, pHead2):
        if not pHead1:
            return pHead2
        if not pHead2:
            return pHead1
        
        if pHead1.val <= pHead2.val:
            self.p = pHead1
        else:
            self.p = pHead2
        while(pHead1 and pHead2):
            if pHead1.val <= pHead2.val:
                temp = pHead1.next
                pHead1.next = pHead2
                pHead2 = temp
                pHead1 = pHead1.next
            else:                
                temp = pHead2.next
                pHead2.next = pHead1
                pHead1 = temp
                pHead2 = pHead2.next
        if not pHead1 and pHead2:
            pHead1 = pHead2
        if not pHead2 and pHead1:
            pHead2 = pHead1
        return self.p

4 复杂链表的复制

题目描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

解题思路:不受c的影响,这道题还是很好做的,用递归就解决了.

class Solution:
    # 返回 RandomListNode
    def Clone(self, pHead):
        if not pHead:
            return None
        temp = RandomListNode(pHead.label)        
        temp.random = pHead.random
        temp.next = self.Clone(pHead.next)
        return temp

5 两个链表的第一个公共节点

题目描述

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

解题思路:如果有公共节点,则两个链表的next指向的是相同的.目前能想到的方法是,分别求为2个链表长度n1和n2,两个长度之差为n2-n1,长的先走n2-n1,短的再走,当他们next相同则是第一个公共节点.

class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        if not pHead1 or not pHead2:
            return None
        n1 = 1
        n2 = 1
        p1 = pHead1
        p2 = pHead2
        while(pHead1.next):
            pHead1 = pHead1.next
            n1 = n1+1
        while(pHead2.next):
            pHead2 = pHead2.next
            n2 = n2+1
        if pHead1 == pHead2:
            i = 0
            if n1<=n2:
                while(i<n2-n1):
                    p2 = p2.next
                    i = i+1
            else:
                while(i<n1-n2):
                    p1 = p1.next
                    i = i+1
            while(p1):
                if p1 == p2:
                    return p1
                p1 = p1.next
                p2 = p2.next
        else:
            return None

6 链表中环的入口节点

题目描述

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

解题思路:先判断是否含有环,有的话一个先走一个后走,两个肯定会碰到一起.如果碰到一起了,一个动一个不动来计算这个环的大小.环大小为N,则一个指针先走N步,然后两个指针一起走,相遇地发就是环的入口.

class Solution:
    def EntryNodeOfLoop(self, pHead):
        if not pHead:
            return None
        p1 = pHead
        p2 = pHead
        fla = False
        while(p1.next):
            p1 = p1.next
            p2 = p2.next.next
            if p1 == p2:
                fla = True
                n = 1
                p2 = p2.next
                while(p1 != p2):
                    p2 = p2.next
                    n = n+1
                break
        if fla == True:
            p11 = pHead
            p12 = pHead
            for i in range(n):
                p11 = p11.next
            while(p11 != p12):
                p11 = p11.next
                p12 = p12.next
            return p11
        else:
            return None

7 删除链表中的重复结点

题目描述

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

解题思路:这个题目需要考虑表头重复的情况.

猜你喜欢

转载自blog.csdn.net/woshicao11/article/details/81611710
今日推荐