算法训练营打卡Day5

今天是周天,本来可以休息一天,但是考虑到昨天还有两道题目没有完成,于是继续打卡。

题目1.

07.链表相交

*附一个思路强大、简洁但不简单的代码(膜拜)希望有人能给我讲解一下

个人认为比较好的讲解思路链接:

https://www.bilibili.com/video/BV1u341187v3/share_source=copy_web&vd_source=1261b97a33f42388f92b473554874c36

Python版本代码:

考虑使用双指针的方法来解决问题,同时考虑链表长度可能不同的情况。

class Solution:

    def getIntersectionNode(self, headA, headB):

       #首先,通过遍历链表headAheadB,分别计算出它们的长度lenAlenB。这是通过两个循环实现的,每个循环使用一个指针cur遍历链表,每遍历一个节点,长度就增加1

        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

         '''

      接下来,代码通过比较lenAlenB的大小,决定哪个链表更长。为了让两个指针在相同的起点 开始遍历(即它们同时到达链表末尾或者相交点的位置),较长的链表需要比较短的链表多走一些步数。

      如果lenA > lenB,则交换curAcurB,以及lenAlenB的值,确保curB指向较长链表的头节点,lenB为较长链表的长度。

      然后,通过for循环让curB向前移动 (lenB - lenA) 步,这样curAcurB就位于距离链表末尾相同距离的位置了,  如果链表相交,则位于相交点;如果不相交,则都位于末尾的None

        '''

        if lenA > lenB:     # 让curB为最长链表的头,lenB为其长度

            curA, curB = curB, curA

            lenA, lenB = lenB, lenA

        for _ in range(lenB - lenA):  # 让curA和curB在同一起点上(末尾位置对齐)

            curB = curB.next

        '''

        最后,使用两个指针curAcurB同时遍历两个链表。由于它们现在位于距离链表末尾相同距离的位置,所以它们要么同时到达链表末尾(如果链表不相交),要么在相交点相遇。

        使用一个while循环遍历链表,直到curAcurB到达链表末尾(None)。在每次循环中,检查curAcurB是否相等。如果相等,则说明它们相遇在相交点,返回该节点。

        while curA:        

            # 遍历curA 和 curB,遇到相同则直接返回

            if curA == curB:

                return curA

            else:

                curA = curA.next

                curB = curB.next

        #如果循环结束都没有返回,则说明链表不相交,返回None

        return None

总结&分析交换的原因

在解决两个链表相交问题时,如果链表A的长度大于链表B的长度,则进行curAcurB以及lenAlenB的交换操作,主要是出于优化遍历过程、确保两个指针能够同时到达链表末尾(如果链表不相交)或相交点(如果链表相交)的考虑。

交换原因分析

  1. 确保同时遍历
    当两个链表长度不等时,直接从一个链表的头节点开始遍历到另一个链表的头节点会导致它们在遍历过程中永远无法“对齐”。例如,如果链表A比链表B长,那么当遍历完链表B后,链表A的指针还没有到达末尾。通过交换,我们可以确保较长的链表(curB)的指针在遍历过程中“等待”较短的链表(curA)的指针,以便两者能在某个点(相交点或末尾)相遇。

  2. 简化逻辑
    交换后,我们可以使用一个统一的循环来处理两个链表的遍历,而不需要编写额外的逻辑来处理不同长度的链表。这样可以使代码更加简洁和易于理解。

题目2. 

环形链表II

题目链接. - 力扣(LeetCode)

讲解链接把环形链表讲清楚! 如何判断环形链表?如何找到环形链表的入口? LeetCode:142.环形链表II_哔哩哔哩_bilibili

颇有挑战,笔者实力有限,读者可参考链接。

总结:要掌握链表的基本操作(增删改查),以及虚拟头结点的技巧,最后结合快慢指针和迭代、递归等技巧。

​​​​​​代码随想录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值