day4 | 19. 删除链表的倒数第N个结点,24. 两两交换链表中的节点,

19. 删除链表的倒数第N个结点

 

题目描述

 

删除链表的倒数第n个结点,并且返回链表的头节点

 

思路

 

1. 先确定链表结点数,得到length

2. 再遍历到第length-n个结点上,改变其指针域上面的值为指向下下的结点,或者说使得指针域的值和下一个结点内指针域的值相等,实现删除第n个结点的功能

3. 暂且不考虑特殊情况,取cur=head,遍历length-n-1次到达目的地,此时cur指向第length-n个结点,执行上一步指针域重新赋值的操作

4. 考虑特殊情况,单列出来,当length-n=0,那么length-1小于小于0,会出现问题。

5. 单独解决这个问题,创建一个虚拟头指针,等于说是实现了cur向右移动-1步的操作,然后再执行指针域重新赋值的操作,返回dummy.next。

(貌似leetcode中的head就是第一个结点地址的意思,head.value就是第一个值,head.next就是下一个节点的地址值)

 

代码如下

复制代码
# 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]:
        def getlength(head):
            cur=head
            length=0
            while(cur!=None):
                cur=cur.next
                length+=1
            return length
        
        nn=getlength(head)
        dummy=ListNode(next=head)
        del_num_front=nn-n
        cur=head
        if del_num_front==0:
            # head=head.next # 这样写其实也行
            dummy.next=dummy.next.next
            return dummy.next
        else:
            for i in range(del_num_front-1):
                cur=cur.next
  
            cur.next=cur.next.next
           return head
复制代码

 

看了答案改进后的代码,可以从一开始就用虚拟头结点。

 

复制代码
class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        dummy = ListNode(0)
        dummy.next = head 

        #step1: 获取链表长度
        cur, length = head, 0 
        while cur:
            length += 1
            cur = cur.next 
        
        #step2: 找到倒数第N个节点的前面一个节点
        cur = dummy
        for _ in range(length - n):
            cur = cur.next
        
        #step3: 删除节点,并重新连接
        cur.next = cur.next.next
        return dummy.next 
复制代码

 

 

24. 两两交换链表中的结点

 

题目简述

 

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

 

思路

 

迭代交换

1. 创建哑结点dummyHead,令dummyHead.next=head。

2. 令temp表示当前到达的结点,初始时temp=dummyHead,每次交换temp后面的两个结点

3. 交换之前结点关系temp→node1→node2,交换之后temp→node2→node1

 

代码如下

 

复制代码
class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        dummyHead = ListNode(0)
        dummyHead.next = head
        temp = dummyHead
        while temp.next and temp.next.next:
            node1 = temp.next
            node2 = temp.next.next
            temp.next = node2
            node1.next = node2.next # 这一句和下一句不能交换,否则找不到node2.next了
            node2.next = node1 
            temp = node1
        return dummyHead.next
复制代码

 

 

142. 环形链表

 

题目描述 略

 

思路:

 

快慢指针法

1. 定义fast和slow指针,fast每次走两步,slow每次走1步

2. 假设head离入口处有a步距离;从入口处到最右侧有b-1个结点,不计算入口处结点,那么从入口处出发,再次回到入口处,需要走k步;如此,链表总计有a+k的结点。

3. 假设slow在离循环入口b步处与fast相遇,那么应该有a+nk+b=2a+2b,a=nk-b,令k=b+c,则有a=c+(n-1)(b+c),从相遇点到入环点的距离加上n-1圈的环长,恰好等于从链表头部到入环点的距离

4. 因此,当发现slow与fast相遇时,我们在额外使用一个指针ptr。起始,它指向链表头部;随后,它和slow每次向后移动一个单位。最终,它们会在入环点相遇

 

代码如如下

复制代码
class Solution(object):
    def detectCycle(self, head):
        fast, slow = head, head
        while True:
            if not (fast and fast.next): return
            fast, slow = fast.next.next, slow.next
            if fast == slow: break
        fast = head
        while fast != slow:
            fast, slow = fast.next, slow.next
        return fast
复制代码

 

 

面试题 02.07. 链表相交

 

题目描述

 

给你两个单链表的头结点headA和headB,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回null。

 

思路

如这题应该是比较明显的双指针题,要是能实现一种算法让两个指针分别从A和B点往C点走,两个指针分别走到C后,又各自从另外一个指针的起点,也就是A指针第二次走从B点开始走,B指针同理,这样,A指针走的路径长度 AO + OC + BO 必定等于B指针走的路径长度 BO + OC + AO,这也就意味着这两个指针第二轮走必定会在O点相遇,相遇后也即到达了退出循环的条件。

 

代码如下

 

复制代码
# 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:
        ta, tb = headA, headB
        while ta != tb:
            ta = ta.next if ta else headB
            tb = tb.next if tb else headA
        return tb
复制代码

 

 

 

总结


1. leetcode里面的头结点貌似就是第一个结点

2. 学会使用快慢指针法

3. 学会面试题中的互补思想

 

posted @   blueCP1999  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示