• 剑指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
    

      

  • 相关阅读:
    C++ 课程设计——电梯调度系统
    PAT 1006 Sign In and Sign Out 查找元素
    PAT 1005 Spell It Right 字符串处理
    C++ 词汇表
    四六级分数竟是这样算出来的!交白卷都不会得零分 (转)
    以太坊智能合约部署
    如何设计一个通证经济体系?(转载)
    以太坊上那些暴力“利”的应用(转载)
    geth搭建以太坊私链及常用操作
    ubuntu18.04 安装 QQ
  • 原文地址:https://www.cnblogs.com/chaojunwang-ml/p/11300642.html
Copyright © 2020-2023  润新知