1、判断两个链表是否有交点,假设不带环
问题描述:如果两个链表相交,则返回交点,如果不相交,则返回NULL
解题思路一:(1)先求出两个链表的长度l1,l2
(2)求出长度的差值k
(3)让较长的链表先走k步,然后两个链表一起向后移动,如果有相等的节点,则说明链表相交
当然还要考虑链表为空的情况,如果至少一个链表为空,则直接返回NULL
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
/**
* @param headA: the first list
* @param headB: the second list
* @return: a ListNode
*/
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
// write your code here
ListNode* h1=headA;
ListNode* h2=headB;
int L1,L2,k;
if(headA==NULL || headB==NULL)
{
return NULL;
}
while(h1)
{
L1++;
h1=h1->next;
}
while(h2)
{
L2++;
h2=h2->next;
}
if(L1<L2)
{
h1=headB;
h2=headA;
L1^=L2;
L2^=L1;
L1^=L2;
}
else
{
h1=headA;
h2=headB;
}
k=L1-L2;
while(k>0)
{
h1=h1->next;
--k;
}
while(h1!=h2)
{
h1=h1->next;
h2=h2->next;
}
return h1;
}
};
解题思路二:如果有解决过链表的带环问题的话,可以将这道题转化成链表的带环问题,也就是先遍历其中一个链表,到第一个链表的尾部之后,让该链表指向另一个链表的头部,由此可以将这个问题转化为链表环的入口点的问题。
2、判断两个链表是否有交点,假设链表带环
问题描述:如果两个链表相交,则返回交点,如果不相交,则返回NULL
解题思路:
pNode IsCrossWithCircle(pNode pHead1, pNode pHead2)//判断两个链表是否相交,若相交,求交点(假设链表可能带环)
{
pNode p1 = HasCircle(pHead1);//求链表1的相遇节点
pNode p2 = HasCircle(pHead2);//求链表2的相遇节点
pNode p11 = p1;
pNode pret1 = NULL;
pNode pret2= NULL;
pNode pret3 = NULL;
pNode NewMeet = NULL;
int iret = 0;
if ((NULL == pHead1 || NULL == pHead2) || (p1 && NULL == p2) || (p2 && NULL == p1))//若任意一个链表为空或者只有一个链表带环,则不可能相交
{
return NULL;
}
if (NULL== p1 && NULL== p2)//两个链表都不带环
{
iret = IsCross(pHead1, pHead2);//不相交
if (0 == iret)
return NULL;
else//相交
{
pret1 = GetCrossNode(pHead1, pHead2);
return pret1;//返回交点
}
}
if (p1 && p2)//两个都带环
{
pret2 = GetEnterNode(pHead1, p1);//求出pHead1的入口点
pret2->next = pHead1;//指向自己
NewMeet = HasCircle(pHead2);//求链表2的相遇节点
pret3 = GetEnterNode(pHead2, NewMeet);//求出链表2的入口点
return pret3;
}
else
return NULL;//不相交
}