题目描述:
Write a program to find the node at which the intersection of two singly linked lists begins.
Notice
- 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.
The following two linked lists:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
begin to intersect at node c1.
Your code should preferably run in O(n) time and use only O(1) memory.
这题我觉得有歧义啊,题目说两个list有intersection,我就不由自主的去考虑他们intersect完了还会分开的可能性。结果想了半天,看了答案才知道题目其实说的是有共同的tail,然后找这个common tail的起始点。这就很简单了:因为tail是相同的,而A和B可能长度不同,所以我们可以先align他们的header,也就是说让长的list先从头走几步,使得新的header到tail的距离和短的list相等。这样,再让两个header同时往前走,如果看到common node就返回。
Mycode(AC = 31ms):
/**
* 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
// get length of list A and B
int lenA = getListLength(headA);
int lenB = getListLength(headB);
// always assume B is longer than A
if (lenA > lenB) {
return getIntersectionNode(headB, headA);
}
else {
int diff = lenB - lenA;
ListNode *nodeA = headA, *nodeB = headB;
// align B and A's header
while (diff > 0) {
nodeB = nodeB->next;
diff--;
}
// go ahead together, to find whether
// the intersection begins
while (nodeA && nodeB) {
if (nodeA->val == nodeB->val) {
break;
}
nodeA = nodeA->next;
nodeB = nodeB->next;
}
return nodeA;
}
}
int getListLength(ListNode *head) {
int len = 0;
ListNode *node = head;
while (node) {
node = node->next;
len++;
}
return len;
}
};