力扣刷题8

75 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情


相交链表

在这里插入图片描述

解题思路

1.先求出两个链表的长度,求出它们的差值。 2.让长的链表先走差值步。 3.然后两人链表同时走,发现有地址相同的时候就返回该地址的节点。没有就返回空。

代码

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode *curA=headA,*curB=headB;
    int lenA=0,lenB=0;
    while(curA)
    {
        curA=curA->next;
        lenA++;
    }

    while(curB)
    {
        curB=curB->next;
        lenB++;
    }
    struct ListNode *shorts=headA,*longs=headB;
    if(lenA>lenB)
    {
        shorts=headB;
        longs=headA;
    }
    int k=lenA>lenB?lenA-lenB:lenB-lenA;
    while(k--)
    {
        longs=longs->next;
    }
    while(shorts&&longs)
    {
        if(shorts==longs)
        return shorts;
        else
        {
            shorts=shorts->next;
            longs=longs->next;
        }
    }
    return NULL;
}

环形链表1

在这里插入图片描述

解题思路

本题用快慢指针进行解决,快指针走2步,慢指针走一步。当两个指针相等时即存在环。

代码

bool hasCycle(struct ListNode *head) {
    struct ListNode *slow,*quick;
    slow=quick=head;
    while(quick&&quick->next)
    {
        slow=slow->next;
        quick=quick->next->next;
        if(slow==quick)
        return true;
    }
    return false;
}

环形链表2

在这里插入图片描述

解题思路

==思路1:== 先用快慢指针找到他俩相遇的节点,然后一个从头开始走,一个从相遇点开始走,当它们相遇的时候即为环的第一个节点。 ==证明== 假设不是环的长度为L,环的长度为C。这里L表达节点的个数。 快指针一次走两步,慢指针一次走一步,当慢指针开始进入环的时候,快指针走了L+N*C+Y(N表示整数,Y表示不足1圈的步数),慢指针走了L。 这时,慢指针和快指针开始了追击。当快,慢指针相遇的时候。假设慢指针在环中走了X步,快指针走了C-Y+X步。 慢指针:L+X 快指针:L+(N+1) * C+X 由快慢指针的关系: 2(L+X)=L+(N+1) * C+X =>L=(N+1)*C-X=> L=N * C+(C-X) ==L=N * C+(C-X)== 在这里插入图片描述

从这个表达式中可以看出来一个指针从头开始走,另一个从相遇点开始走,相遇时就是环的第一个节点。 ==思路2:== 同样需要快慢指针,当快慢指针相遇的时候,把该节点制成空。这时题目就变成找两个链表的相交节点。注意: 最后要把破坏的链表恢复到原来的模样。

代码

思路1:

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode  *slow,*quick;
    slow=quick=head;
    while(quick&&quick->next)
    {
        slow=slow->next;
        quick=quick->next->next;
        if(slow==quick)
        {
            struct ListNode* cur=head;
            while(cur!=slow)
            {
                cur=cur->next;
                slow=slow->next;
            }
             return cur;
        }
    }
    return NULL;
}

思路2:

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode *slow,*quick;
    int L1,L2;
    L1=L2=0;
    slow=quick=head;
    while(quick&&quick->next)
    {
        slow=slow->next;
        quick=quick->next->next;

        if(slow==quick)
        {
            struct ListNode*cur=head;
            struct ListNode* newhead=slow->next;
            slow=slow->next;
            quick->next=NULL;
            while(cur)
            {
                cur=cur->next;
                L1++;
            }
            while(slow)
            {
                slow=slow->next;
                L2++;
            }
            int divalue=L1>L2?L1-L2:L2-L1;
            struct ListNode *shorts=head,*longs=newhead;
            if(L1>L2)
            {
                shorts=newhead;
                longs=head;
            }
            while(divalue--)
            longs=longs->next;
            while(shorts!=longs)
            {
                shorts=shorts->next;
                longs=longs->next;
            }
            quick->next=newhead;
            return shorts;
        }
    }
    return NULL;
}