代码随想录算法训练营第四天|24.两两交换链表中的节点,19.删除链表的倒数第n个节点,160.相交链表,142.环形链表

文档:programmercarl.com

今天的题算是链表的扩充题吧,学完感觉双指针真好用(就是自己想不出来),难度的话,我觉得24和142比较难,其他还好,甚至能暴力解

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

这一题是我今天写过最难的题,直接当头一棒,以至于我现在还有点懵逼

直接放代码吧,我肯定讲不明白

class Solution(object):
    def swapPairs(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        vir_head = ListNode(next = head)
        cur = vir_head

        while cur.next and cur.next.next:
            temp = cur.next # 记录的是1号节点
            temp1 = cur.next.next.next # 记录的是3号节点

            cur.next = cur.next.next # vir节点next指向2节点
            cur.next.next = temp #2号节点指向1节点
            temp.next = temp1 # 1号节点指向3号节点
            cur = cur.next.next # cur指针移动到1号节点

        return vir_head.next

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

这道倒是第一次就AC了,我刚开始没有用双指针,而是用的暴力解,就是先遍历找出链表的长度,然后用长度-n就可以算出要删除第几个节点了,再遍历到对应的位置删除就行

class Solution(object):
    def removeNthFromEnd(self, head, n):
        vir_head = ListNode(next = head)
        cur = vir_head
        len = 0 # 计数器

        while cur.next != None: # 遍历得出链表的长度
            cur = cur.next
            len += 1

        cur = vir_head
        for i in range(len - n): # 遍历第二次到倒数n的位置处
            cur = cur.next

        cur.next = cur.next.next # 删除节点

        return vir_head.next # 返回结果

还有一种就是双指针写法了,先让fast指针走到前面去,正好和slow指针形成一个差值n,然后二者同时向前走,当fast指针走到结尾时,说明slow指针走到了倒数第n位

class Solution_answer(object):
    def removeNthFromEnd(self, head, n):
        vir_head = ListNode(next = head)

        slow = vir_head #定义慢指针
        fast = vir_head #定义快指针

        for i in range(n + 1): #快指针先遍历到目标位置
            fast = fast.next

        while fast != None: #快慢指针一起走,直到快指针走到终点
            slow = slow.next
            fast = fast.next

        slow.next = slow.next.next #删除节点

        return vir_head.next

160.相交链表

这道题我没有思路,但是一看答案代码就明白了,不难,原来遍历求长度也不是不行

首先计算出每个链表的长度,然后长链表减去差值后,就和短链表的起始位置一样了,然后二者开始同时遍历,直到碰见相同的节点,这个节点就是相交节点了

class Solution(object):
    def getIntersectionNode(self, headA, headB):
        lenA = 0
        lenB = 0
        cur = headA
        while cur:
            cur = cur.next
            lenA += 1
        cur = headB
        while cur:
            cur = cur.next
            lenB += 1

        curA = headA
        curB = headB
        if lenA > lenB: # 让curB为最长链表的头
            curA, curB = curB, curA
            lenA, lenB = lenB, lenA

        for _ in range(lenB - lenA): # 让curB指针移动到和curA同一位置
            curB = curB.next

        while curA:
            if curA == curB:
                return curA
            else:
                curA = curA.next
                curB = curB.next
        return None # 没有相同的节点,就返回None

142.环形链表

这个题吧,emmmm,还是得看数学功底,我数学不好,讲不明白,但是看着那张动图还是能写出来代码的

"""
数学问题,麻了,果然算法就是灵活的,双指针是真的猛啊
"""
class Solution(object):
    def detectCycle(self, head):
        # 首先判断是否有环
        fast = head
        slow = head
        indexA, indexB = head, None # 找出环的入口

        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next

            if fast == slow: # 找到两个指针相遇的节点
                indexB = slow
                while indexA != indexB: # 当indexA和indexB相遇的时候,说明该节点就是环入口
                    indexA = indexA.next
                    indexB = indexB.next
                return indexA
        return None

(动图可以去网站找,这里就不粘贴了)

等后天考完试就可以好好写算法了,呜呜

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值