leetcode160.相交链表
题目
找到两个单链表相交的起始节点。
如果两个链表没有交点,返回 null。
在返回结果后,两个链表仍须保持原有的结构。
可假定整个链表结构中没有循环。
程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。
方法1
思路
两个指针分别从A和B开始,一个先走完A再走B,一个先走完B再走A,交点前的长度差被抵消,两个指针会在交点处相遇。
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) {
if(headA == NULL || headB == NULL){
return NULL;
}
ListNode* p = headA;
ListNode* q = headB;
//两个指针分别从A和B开始,把AB都走一遍,交点前的长度差被抵消,两个指针会在交点处相遇
while(p != q){
if(p == NULL)
p = headB;
else
p = p->next;
if(q == NULL)
q = headA;
else
q = q->next;
}
return p;
}
};
方法2
思路
先将链表A的尾部和链表B的头部相连,如果A和B不相交,则不成环;如果A和B相交,则会构成环,转换为环形链表求入环点问题。注意返回前恢复链表的原始结构。
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) {
if(headA == NULL || headB == NULL){
return NULL;
}
//人工构环,将A的尾指向B的头
ListNode* p = headA;
while(p->next != NULL)
p = p->next;
p->next = headB;
//转化成找链表环进入点的问题
ListNode* fast = headA;
ListNode* slow = headA;
ListNode*q = headA;
while(fast != NULL && fast->next != NULL){
fast = fast->next->next;
slow = slow->next;
if(fast == slow){
while(q != slow){
q = q->next;
slow = slow->next;
}
//恢复链表原始结构
p->next = NULL;
return q;
}
}
//恢复链表原始结构
p->next = NULL;
return NULL;
}
};