携手创作,共同成长!这是我参与「掘金日新计划 · 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;
}