链表 160.相交链表
题目
编写一个程序,找到两个单链表相交的起始节点。如下图有两条链表,listA = [4,1,8,4,5], listB = [5,0,1,8,4,5],则应当返回相交的起始节点,即8的索引或指针。
分析
看到这道题,其本质就是找到链表公共的部分,所以我们通常很容易想到的方法就是暴力破解,即遍历其中的一条链表A并查询B中是否与其相同的节点,当然这是以更长的时间为代价。时间复杂度为O(n*m),空间复杂度为O(1)。
另外,也有一个比较巧妙的思路,可以看到公共的部分是链表的末尾,此时我们尝试把两条链表相互接起来。可以看到末尾部分的也正是我们要找的公共的部分。故定义临时指针A,B初始化为listA和listB的头结点,让其遍历链表,当A遍历完listA时,在把A定位到listB的头结点,当B遍历完listB时,再把B定位到listA的头结点,最后他们会到达交点处。时间复杂度为O(n+m),空间复杂度为O(1)。
[4,1,8,4,5,5,0,1,8,4,5]
[5,0,1,8,4,5,4,1,8,4,5]
代码
/**
*C语言
*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
if( !headA || !headB )
{
return NULL;
}
struct ListNode *A = headA;
struct ListNode *B = headB;
while( A != B )
{
A = A ? A->next : headB;
B = B ? B->next : headA;
}
return A;
}
/**
*Java
*/
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if( headA == null || headB == null )
{
return null;
}
ListNode A = headA , B = headB;
while ( A != B )
{
A = A != null ? A.next : headB;
B = B != null ? B.next : headA;
}
return A;
}
}
纸上得来终觉浅,绝知此事要躬行