题目二.png
解决思路
思路一
遍历两个链表到末尾节点,同时分别对两个链表长度计数,判断末尾节点是否相同,相同则说明交叉,将长的链表先移动长度差个节点,同时遍历两个链表,第一个相同节点即为所求。
注意,可能短链表是长链表的一部分,或者两个链表完全一样。
example :
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headA == NULL|| headB == NULL ) return NULL;
int cntA=0;
int cntB=0;
ListNode* curA=headA;
ListNode* curB=headB;
int sub=0;
while(1)
{
if(!curA->next&&!curB->next)
break;
if(curA->next)
{
cntA++;
curA=curA->next;
}
if(curB->next)
{
cntB++;
curB=curB->next;
}
}
if(curA!=curB)
return NULL;
curA=headA;
curB=headB;
if(cntA>cntB)
{
sub=cntA-cntB;
while(sub)
{
curA=curA->next;
sub--;
}
}
else
{
sub=cntB-cntA;
while(sub)
{
curB=curB->next;
sub--;
}
}
while(curA!=curB)
{
curA=curA->next;
curB=curB->next;
}
return curA;
}
};
思路二
将第一个链表的末尾节点指向第二个节点的头部(返回结果前要拆开),问题转换为求单链表是否有环,环入口即为所求交叉点。
合并后的单链表头为第一个链表的头,判断是否有环的方式为,定义两个指针,一个slow,每次前进一步,一个fast,每次前进两步,
直至slow == fast 或者 fast走到末尾,slow==fast说明有环,fast走到末尾说明无环。判断有环后,定义两个指针,一个指向刚才的相遇点,一个指向合并后的链表头,相等即为环入口(两个链表组成一个循环单链表情况),两个指针每次移动一步,直到找到相同点,即为环入口。
判断环方式,求环入口方法证明略。
example:
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func getIntersectionNode(headA, headB *ListNode) *ListNode {
if headA == nil || headB == nil {
return nil
}
var last *ListNode
for cur := headA; ; {
if cur.Next == nil {
last = cur
cur.Next = headB
break
}
cur = cur.Next
}
fast, slow := headA, headA
find := false
for ; fast != nil && fast.Next != nil; {
slow = slow.Next;
fast = fast.Next.Next;
if slow == fast {
find = true
break
}
}
if ! find {
last.Next = nil
return nil
}else {
fast = headA
for {
if slow == fast {
last.Next = nil
return slow
}
slow = slow.Next
fast = fast.Next
}
}
}
网友评论