代码随想录算法训练营4day-python|24. 两两交换链表中的节点、19. 删除链表的倒数第 N 个结点、160. 相交链表、142. 环形链表 II

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

思路:递归的终止条件是链表中没有节点,或者链表中只有一个节点时是无法进行交换的,可以直接返回该节点。否则,我们递归交换链表 head.next.next,记交换后的头节点为 cur,然后我们记 head 的下一个节点为 pre,令 pre 指向 head,而 head 指向 cur,最后返回 pre。

总结:打卡虽迟但到。自己手动画个过程图,再结合卡哥的视频讲解后,对这道题的理解加深,一下子就get到了

代码:①递归

def swapPairs(self, head):
    if head is None or head.next is None:  # 终止条件
        return head
    cur = self.swapPairs(head.next.next)  # 递归,交换后的头节点
    pre = head.next  # head的下一个节点
    pre.next = head  # 指向head
    head.next = cur  # 指向cur
    return pre

②迭代

def swapPairs(self, head):
    dummy_head = ListNode(next=head)  # 虚拟头结点
    cur = dummy_head
    while cur.next and cur.next.next:  # 必须有两个才能进行交换
        temp = cur.next  # 先保存下来,防止被修改
        temp1 = cur.next.next.next
        cur.next = cur.next.next
        cur.next.next = temp
        temp.next = temp1
        cur = cur.next.next  # cur向后移两位,进行后面的交换
    return dummy_head.next

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

思路:使用快慢指针,快指针先移动N步,快慢指针再同时移动。当快指针指向空时,慢指针指向的就是目标,但因为要先找到节点的前一个,所以快指针要先走N+1步。

总结:多看多学,把别人的思路搞会了,就是你的思路~

代码:①快慢指针

def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
    # 删除链表中的倒数第N个节点
    dummy_head = ListNode(next=head)
    slow = fast = dummy_head
    # 快指先走N+1步
    for i in range(n + 1):
        fast = fast.next
    # 快慢指针同时走,直到fast指针到达末尾,此时slow到达倒数第N个节点的前一个节点
    while fast:
        slow = slow.next
        fast = fast.next
    # 删除slow指针的下一个节点,重新连接
    slow.next = slow.next.next
    return dummy_head.next

三、160. 相交链表

思路:题目让求的是链表相交的节点,所以a 、b的指针都要走一遍headA、headB两个链表,a、b相遇的地方就是相交的点。

总结:其实光看题目描述的时候给我搞懵逼了,但后面看人家的题解评论乐了,解题还整上浪漫氛围了呢。“错过的人就算走过的路依然会错过。而注定相遇的人,就算走到尽头见不到你,我也会走你走过的路,而你也走过我走过的路”!!!!行了,行了,代码我搞不会,这浪漫我依然搞不会。就应该叉出去(bushi)

代码:①

def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
    if not headA or not headB:
        return None
    A, B = headA, headB
    # 遍历指针相交点
    while A != B:
        A = A.next if A else headB
        B = B.next if B else headA
    return A

代码②

def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
    # 初始化指针还有长度
    flagA, flagB = headA, headB
    lenA, lenB = 0, 0
    # 求链表A的长度
    while flagA:
        flagA = flagA.next
        lenA += 1
    # 链表B的长度
    while flagB:
        flagB = flagB.next
        lenB += 1
    # 重新定向表头
    flagA, flagB = headA, headB
    if lenA > lenB:
        flagA, flagB = flagB, flagA
        lenA, lenB = lenB, lenA
    # 让指针flagA移到和B链表同等长度的位置上
    for _ in range(lenB - lenA):
        flagB = flagB.next
    # 然后两个指针flagA和flagB同时遍历
    while flagA:
        if flagA == flagB:
            return flagA
        else:
            flagA = flagA.next
            flagB = flagB.next
    # 没有相遇,返回 None
    return None

四、142. 环形链表 II

思路:其规律是用一个快指针fast和慢指针slow,快指针每次走两步,慢指针每次走一步,若有环的情况下他们两个肯定是会重合的。

总结:不会写代码的总结不是一个好总结,好吧,我不是一个好总结。今天学得有点多,需要好好消化一下,其实在学习完了后,总结时是会让知识在脑子里哗啦啦的翻一遍,把学到的东西再重新巩固了一下。脑电量有点低了,散了吧~~~

代码:

def detectCycle(self, head: ListNode):
    fast = head
    slow = head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:  # 快慢指针重合说明存在环,再派一个指针从头节点和慢指针同步移动
            slow = head
            while slow != fast:
                slow = slow.next
                fast = fast.next
            return slow  # 新指针和慢指针重合的节点即为环入口节点
    return None

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值