一天一道LeetCode
本系列文章已全部上传至我的github,地址:ZeeCoder‘s Github
欢迎大家关注我的新浪微博,我的新浪微博
欢迎转载,转载请注明出处
(一)题目
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.
(二)解题
题目大意:两个单向链表,有一段重复区域,找出其中的第一个交叉节点。
解题思路:题目要求时间复杂度O(n)和空间复杂度O(1),所以利用辅助空间的方法都不行。
如果两个链表会交叉,那么他们的最后一个节点肯定相同,如果是双向链表,可以从尾节点开始,找到第一个出现分离的节点即可。可是,题目要求不能破坏初始链表。这种方法也行不通。
如果两个链表的长度一样的话,从头开始往后,可以找到第一个交叉点。
记链表的长度为len1和len2,可以让长链表先走abs(len1-len2)步,再两个一起往后找。即可找到第一个交叉点。
具体解释见代码:
/**
* 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 lenA = getlength(headA);//统计链表A的长度
int lenB = getlength(headB);//统计链表B的长度
int diflen = lenA-lenB;//计算差值
//lenA<lenB的情况
ListNode *longList = headA;//lenA<lenB的情况
ListNode *shortList = headB;
//lenA>lenB的情况
if(diflen<0)
{
longList = headB;
shortList = headA;
diflen = -diflen;
}
while(diflen>0&&longList!=NULL)//让长链表先走diflen步
{
longList = longList->next;
diflen--;
}
while(longList!=NULL&&shortList!=NULL)//两个链表一起往后走
{
if(longList->val == shortList->val) return longList;//找到交叉节点
else{
longList = longList->next;
shortList = shortList->next;
}
}
return NULL;
}
int getlength(ListNode *head)
{
int n = 0;
ListNode *phead = head;
while(phead!=NULL)
{
phead = phead->next;
n++;
}
return n;
}
};