代码随想录算法训练营day4(链表)

华子目录

两两交换链表中的节点

思路

  • 使用虚拟头结点(要操作连续的两个节点,就必须找到其上一个节点),cur指向该节点
  • 在交换之前,先对虚拟节点.next和虚拟节点.next.next.next做临时记录
  • 如果为偶数个节点,则cur.next==None
  • 如果为奇数个节点,则cur.next.next==None
python 复制代码
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
        virtualHead = ListNode()
        virtualHead.next = head
        cur = virtualHead
        while cur.next != None and cur.next.next != None:  # 这里得先判断cur.next != None,不然如果cur.next为None的话,那么cur.next.next就空指针溢出了
            temp1 = cur.next
            temp2 = cur.next.next.next
            cur.next = cur.next.next
            cur.next.next = temp1
            cur.next.next.next = temp2
            cur = cur.next.next
        return virtualHead.next

删除链表的倒数第N个节点

思路

  • 删除第N个节点,那么我们当前遍历的指针一定要指向第N个节点的前一个节点
  • 使用虚拟头结点和left,right双指针,初始时,两个指针都指向虚拟头节点
  • right指针先向后移动N次,之后,双指针一起向后移动,当right为None时,left刚好指向倒数第N个节点
  • 所以right指针一开始向后移动N+1次,这样left就可以指向被删除节点的前一个节点
python 复制代码
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        virtualHead = ListNode()
        virtualHead.next = head
        left = right = virtualHead
        while n+1>0:
            right = right.next
            n -= 1
        while right != None:
            right = right.next
            left = left.next
        left.next = left.next.next
        return virtualHead.next

链表相交

思路1

  • 先遍历出A和B的各个长度lengthA和lengthB
  • 计算出差值temp
  • 最长的从头开始向后遍历temp次
  • 然后curA和curB进行判断,如果相等则返回该节点,如果遍历完了还不相等则返回None
python 复制代码
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        curA, curB = headA, headB
        lengthA = lengthB = 0
        while curA:
            lengthA += 1
            curA = curA.next
        while curB:
            lengthB += 1
            curB = curB.next
        if lengthA > lengthB:
            temp = lengthA - lengthB
            curA, curB = headA, headB
            while temp:
                curA = curA.next
                temp -= 1
            while curA:
                if curA == curB:
                    return curA 
                curA = curA.next
                curB = curB.next
            return None
        else:
            temp = lengthB - lengthA
            curA, curB = headA, headB
            while temp:
                curB = curB.next
                temp -= 1
            while curA:
                if curA == curB:
                    return curA 
                curA = curA.next
                curB = curB.next
            return None

思路2

  • 使用集合先记录一条链表的所有内存地址(哈希表)
  • 再去遍历另一条链表,每遍历一个节点,就判断该节点的内存地址在不在集合中
  • 如果在就返回该节点,不在则返回None
python 复制代码
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        curA, curB = headA, headB
        hash1 = set()
        while curA:
            hash1.add(curA)
            curA = curA.next
        while curB:
            if curB in hash1:
                return curB
            curB = curB.next
        return None

环形链表II

思路

  • 使用left,right快慢指针,两个指针第一次相遇时一定在环中,相遇前,left每次移动一个节点,right每次移动两个节点
  • 当left,right再次相遇时,就是入环口
python 复制代码
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
        left = right = head
        while right and right.next:  # right不为None,right.next也不为None
            left = left.next
            right = right.next.next
            if left == right:
                left = head
                while left != right:
                    left = left.next
                    right = right.next
                return left
        return None
相关推荐
倒头就睡的小比特3 天前
算法竞赛C++常用的STL
c++·算法
默_笙3 天前
🍙 给每个请求过安检:FastAPI 是怎么把校验写进类型注解的
python
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
qq_426003963 天前
启动playwright录制codegen生成自动化测试脚本
python·自动化
虎头金猫3 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
长沙三为智能科技3 天前
家政小程序开发从0到上线:五阶段交付流程与验收清单
python
伞伞悦读3 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
猎头南楼3 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
只睡四小时3 天前
Canvas 弹道联机实战:700 行 + 固定时间步长
python·websocket·html5·游戏开发·canvas
m0_547486663 天前
《数据结构教程》全套 PPT课件2026
数据结构