一、题目描述
Write a program to find the node at which the intersection of two singly linked lists begins.
For example, the following two linked lists:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
begin to intersect at node c1.
Notes:
- If the two linked lists have no intersection at all, return
null
. - The linked lists must retain their original structure after the function returns.
- You may assume there are no cycles anywhere in the entire linked structure.
- Your code should preferably run in O(n) time and use only O(1) memory.
题目解读:给两条链表的头结点,返回两条链表相交的结点,如果不相交返回NULL
思路:容易发现规律,两条链表从尾到相交结点的长度是相同的,因此需要算出两条链表的长度len1,len2。
长的链表先遍历count=| len1-len2 |个结点,然后两条链表再一起遍历,如果发现两个结点相等就返回该结点。
直到遍历完所有的结点没有相等的结点,返回NULL。
c++代码(52ms,40.40%)
/**
* 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) {
//先算出两条链表的长度
int len1=0;
int len2=0;
ListNode *tmp;
tmp=headA;
while(tmp){
len1++;
tmp=tmp->next;
}
tmp=headB;
while(tmp){
len2++;
tmp=tmp->next;
}
int count;
ListNode *current1=headA;
ListNode *current2=headB;
if(len1>len2){
count=len1-len2;
while(count){
current1=current1->next;
count--;
}
}
else{
count=len2-len1;
while(count){
current2=current2->next;
count--;
}
}
while(current1){
if(current1 == current2)
return current1;
else{
current1=current1->next;
current2=current2->next;
}
}
return NULL;
}
};
一种更聪明的方法
思路:要找出两条链表的相同的结点,因为两条链表的长度不同而不好确定从哪开始一起遍历。
但是如下图所示,相互补齐链表,长度就相同了。
c++代码
/**
* 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) {
ListNode *p1=headA;
ListNode *p2=headB;
if(p1==NULL || p2==NULL)
return NULL;
while(p1 != NULL && p2 != NULL && p1 != p2){
p1 = p1->next;
p2 = p2->next;
if(p1 == p2)
return p1;
if(p1 == NULL)
p1=headB;
if(p2 == NULL)
p2=headA;
}//while
return p1;
}
};
思路一样,更简洁的写法:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *cur1 = headA, *cur2 = headB;
while(cur1 != cur2){
cur1 = cur1?cur1->next:headB;
cur2 = cur2?cur2->next:headA;
}
return cur1;
}