链表 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;
    }
}

 

posted @ 2020-07-31 21:42  Rego  阅读(80)  评论(0)    收藏  举报