题目
输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
思路
(来自于官方解答。)这里面求的是两个链表的公共节点,前提条件是两个链表确实有公共节点或者是至少某一链表为空,就直接返回NULL。(当然,这我也是看了解析,才知道,题目没有明说这个前提。)首先考虑最理想的一种情况,那就是两个链表的前面非公共部分的长度相等,这时,直接用双指针的方法各自从链表的头结点开始往后移动,第一个相同节点,便是第一个公共节点。如图1所示。
麻烦的当然是前面非公共部分不相等的情况下,该这么解决这个问题。此时,就是图3的情况了,图2 是一个具体的例子。此时,只需在第一个链表的前面加上第二个链表长度的链表,在第二个链表前面加上第一个链表长度的链表,这样的话,就可以使两个链表的非公共节点的长度是一样的,就可以继续按照前面提到的第一种情况的方法来做了。
代码
具体到代码实现的时候,不用真的是去计算两个链表的长度,只需当遍历两个链表的指针第一次遍历完之后重新指向各自的头结点,接着开始第二遍的遍历,在第二遍的时候,一定可以找到公共节点。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1==NULL||pHead2==NULL){return NULL;}
ListNode*la=pHead1;
ListNode*lb=pHead2;
while(la!=lb){
la=la->next;
lb=lb->next;
if(la!=lb){
if(la==NULL){la=pHead1;}
if(lb==NULL){lb=pHead2;}
}
}
return la;
}
};
说明:做这种刷题的时候,往往对边界的考察很严格。并且,往往题目说的不清楚,有些前提说的不明白,就很烦。哈哈哈哈。我一般都是会大致思考一下解法,然后看看思路解析,有时或许我想的解法考虑的复杂了。但也有时,我就是压根不会写。