代码随想录day4|链表2

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

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

**关键点:**虚拟头结点,只要知道前一个结点的指向才能修改后一个节点的指向。操作指针一定要指向操作的两个节点的前一个节点。
代码随想录day4|链表2_第1张图片

class Solution:
    def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
        res = ListNode(next = head)
        pre = res
        while pre.next and pre.next.next:
            cur = pre.next
            post = pre.next.next

            # pre,cur,post对应最左,中间的,最右边的节点
            # 通过设置空指针达到遍历的目的
            cur.next = post.next
            post.next = cur
            pre.next = post

            pre = cur
        return res.next

19.删除链表的倒数第n和节点

题目描述: 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
关键点: 删除第N个结点,那么指针一定要指向第N个结点的前一个节点。
思路: 通过遍历找到要删除节点的前一个节点,利用快慢指针的思想。

class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        # 关键在于如何得到倒数第n个结点,设置两个节点即可
        head_dummy = ListNode(next = head)
        left,right = head_dummy,head_dummy
        for _ in range(n):
            right = right.next
        while right.next != None:
            left = left.next
            right = right.next
        # 进行删除操作
        left.next = left.next.next
        return head_dummy.next

**编写过程中的问题:**返回的时候直接反悔了head但是head节点,在该代码结构中并没有改变,改变的是虚拟节点的下一个节点。

160.链表相交

题目描述: 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
关键思想: 将两个链表运行到末尾位置齐平的状态,然后判断末尾位置的节点是否相等。找到两个链表的长度之后,将两个链表末尾对齐

		lenA, lenB = 0, 0
        cur = headA
        while cur:         # 求链表A的长度
            cur = cur.next 
            lenA += 1
        cur = headB 
        while cur:         # 求链表B的长度
            cur = cur.next 
            lenB += 1
        curA, curB = headA, headB
        if lenA > lenB:     # 让curB为最长链表的头,lenB为其长度
            curA, curB = curB, curA
            lenA, lenB = lenB, lenA 
        for _ in range(lenB - lenA):  # 让curA和curB在同一起点上(末尾位置对齐)
            curB = curB.next 
        while curA:         #  遍历curA 和 curB,遇到相同则直接返回
            if curA == curB:
                return curA
            else:
                curA = curA.next 
                curB = curB.next
        return None 

142.环形链表II

问题描述: 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
解题:

  1. 判断链表是否环(使用快慢指针的方式判断链表是否有环)
  2. 如果有环,如何找到这个环的入口(通过数学推理找到指针的位置,记录初始位置的指针和相遇位置的指针即可)
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
        slow,fast = head,head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            # 先确定有无相交的结点
            if fast == slow:
                p = head
                q = slow
                while p!=q:
                    p = p.next
                    q = q.next
                return p
        return None

总结

  1. 两两交换链表中的节点:虚拟头结点+cur指针
  2. 删除链表中的第n个结点:虚拟头结点+双指针
  3. 环形链表:快慢指针+如何找到环的入口位置
  4. 链表相交:链表末尾齐平
  5. 反转链表:迭代法
  6. 链表的增删改查操作,主要考察指针的应用

你可能感兴趣的:(链表,数据结构)