剑指offer-链表

1. 链表中环的入口节点

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

思路一:用哈希表存已经遍历过的节点,O(1)复杂度查找,如果再次遇到就是环入口

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def EntryNodeOfLoop(self, pHead):
        # 用哈希表存遍历过的节点,重复的节点为环入口
        if pHead is None or pHead.next is None:
            return None
        hashmap = set()
        p = pHead
        while p:
            if p in hashmap:
                return p 
            hashmap.add(p)
            p = p.next

 

思路二:快慢指针

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def EntryNodeOfLoop(self, pHead):
        # 快慢指针;如果有环,快指针会追上慢指针;再分别从头节点和快慢指针相遇点向后,相遇的节点为环入口
        if pHead is None or pHead.next is None:
            return None
        slow = pHead
        fast = pHead
        while fast:  # 找快慢相遇点
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                break
        slow = pHead  # 找环入口
        while slow != fast:
            slow = slow.next
            fast = fast.next
        return slow

  

 

2. 删除链表中重复的节点

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

思路:需要一个pre作为p的前驱节点,如果遇到重复节点就一直向后遍历到不重复的节点,pre指过去即可。再往后遍历之前需要把p退回到pre,因为后面还是有可能出现和pre重复的节点。特别注意从头节点就开始重复的情况,需要把pHead指向不重复节点。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def deleteDuplication(self, pHead):
        # write code here
        if pHead is None or pHead.next is None:
            return pHead
        pre = None  # 记录p前面的节点
        p = pHead
        while p:
            nextp = p.next
            if nextp and nextp.val == p.val:  # 需要删除节点
                sameVal = p.val  # 向后一直找到不相同节点
                pNeedDel = p
                # 要么从p开始重复到最后,pNeedDel为None;要么pNeedDel指向下一个不重复的节点
                while pNeedDel and pNeedDel.val == sameVal:
                    pNeedDel = pNeedDel.next
                
                if pre is None:  # 如果pre还是None,说明从头节点开始一直重复,头节点要指向下一个不重复节点
                    pHead = pNeedDel  
                    p = pHead  # 继续向后遍历,pre还是None就行了
                else:  # 如果是从头节点后面的节点开始重复,pHead不用变
                    pre.next = pNeedDel  # 删除从p开始的重复节点
                    p = pre  # 要退到开始重复的上一个节点,后面可能出现与pre重复的节点
                    
            else:  # 不需要删除节点,向后遍历
                pre = p
                p = nextp
        return pHead

  

3. 从尾到头打印链表

输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。

思路一:递归

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    # 返回从尾部到头部的列表值序列,例如[1,2,3]
    def printListFromTailToHead(self, listNode):
        # write code here
        if listNode is None:
            return []
        if listNode.next is None:  # 如果只有一个节点
            return [listNode.val]
        return self.printListFromTailToHead(listNode.next) + [listNode.val]   # 后面所有节点值的倒序list + [当前节点值]

 

思路二:list保存,逆序返回

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

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

 

思路三:利用list的操作性质

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    # 返回从尾部到头部的列表值序列,例如[1,2,3]
    def printListFromTailToHead(self, listNode):
        # write code here
        if listNode is None:
            return []
        if listNode.next is None:
            return [listNode.val]
        
        res = [listNode.val]
        p = listNode.next
        while p:
            res = [p.val] + res
            p = p.next
        return res

  

思路四:利用栈的先进后出

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    # 返回从尾部到头部的列表值序列,例如[1,2,3]
    def printListFromTailToHead(self, listNode):
        # write code here
        if listNode is None:
            return []
        if listNode.next is None:
            return [listNode.val]
        res = []
        p = listNode
        while p:
            res.insert(0, p.val)
            p = p.next
        return res

  

 

posted @ 2019-08-04 23:57  王朝君BITer  阅读(180)  评论(0编辑  收藏  举报