每日一题
两个链表的第一个公共节点
思路
分析:
首先,让我们考虑特殊情况,如果两个链表的·长度相同,那我们定义两个指针变量cur1,cur2,使其分别指向两个表头,并让其一起对表一表二逐个遍历,如果cur1等于cur2,则可以直接返回cur1。
- 当cur1不为空时,说明两链表有公共节点,反之,当cur1为NULL,说明两链表无公共节点。
两个链表长度不同,显然不好进行计算。
因此,我们就需要采取办法使cur1和cur2处在相同位置。
方法一
- 我们可以分别求出表一和表二的长度,并算出它们的长度差count,再定义两个指针变量cur1,cur2,使其分别指向两个表头。
- 让长的链表的cur指针先走count个节点
- 最后让cur1和cur2一起每次走一个节点,当其相等时,返回cur1
方法二
设表一长度为A,表二长度为B,则易得:A + B = B + A
由上面的关系,我们定义两个指针变量cur1,cur2,使其分别指向两个表头,并让其同时每次移动一个节点
当cur1为空时,则下次移动时,让cur1指向表二的头,同理,当cur2为空时,则下次移动时,让cur2指向表一的头
- 相当于把整个表二接在表一前,把整个表一接在表二前,这样,两表的长度就相同了
- 如图:
这样,当cur1与cur2相等时,即可返回cur1
实现代码
方法一
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/**
*
* @param pHead1 ListNode类
* @param pHead2 ListNode类
* @return ListNode类
*/
struct ListNode* FindFirstCommonNode(struct ListNode* pHead1, struct ListNode* pHead2 ) {
struct ListNode* cur1, *cur2;
int count1 = 1,count2 = 1,count3;
cur1 = pHead1;
cur2 = pHead2;
while(cur1) //计算表一长度
{;
count1++;
cur1 = cur1->next;
}
while(cur2) //计算表二长度
{
count2++;
cur2 = cur2->next;
}
cur1 = pHead1; //使cur1和cur2重新指向表一表二的头节点
cur2 = pHead2;
count3 = fabs((double)count1 - (double)count2); //计算长度差
//让长的链表先走count3个节点
if(count1 > count2)
{
while(count3--)
cur1 = cur1->next;
}
if(count1 < count2)
{
while(count3--)
cur2 = cur2->next;
}
//找到第一个公共节点
while(1)
{
if(cur1 == cur2)
return cur1;
cur1 = cur1->next;
cur2 = cur2->next;
}
}
方法二
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/**
*
* @param pHead1 ListNode类
* @param pHead2 ListNode类
* @return ListNode类
*/
struct ListNode* FindFirstCommonNode(struct ListNode* pHead1, struct ListNode* pHead2 ) {
struct ListNode* cur1 = pHead1;
struct ListNode* cur2 = pHead2;
while(cur1 != cur2)
{
cur1 = cur1 ? cur1->next : pHead2; //如果cur1为空,那么cur1指向表二的头,否则cur1指向下一个节点
cur2 = cur2 ? cur2->next : pHead1; //cur2同理
}
return cur1;
}