解决相交链表问题

以力扣例题为例:
解决相交链表问题_第1张图片

大思路:结点相交——同一个结点——同一个地址

思路1:

尾结点地址相同则相交:无法找到相交位置;但是使用此方法可以直接判断出不相交的情况!

思路2:

两个链表中,每个结点地址互相比较 时间复杂度为O(n^2)

思路3:

如果两个链表一样长,那么只用比较对应位置是否相等即可,时间复杂度为O(n)

注意:本题不能用逆置的思想,因为每个结点只能有一个next域

那么怎么要它们一样长呢?——采用快慢指针法

对于两个链表有长有短,那么我们通过遍历可以得到两个链表间的长度关系,让长的链表先走差距步,那么此时,两个指针指向的起始位置之后的长度即相等了

curA和curB指针分别指向这两个链表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode* curA=headA;
    struct ListNode* curB=headB;
    //代表A、B链表的长度
    int lenA=0;
    int lenB=0;
    
    //比较尾结点地址可直接排除不相交情况,因此这里寻找尾结点
    while(curA->next){
        lenA++;
        curA=curA->next;
    }
    while(curB->next){
        lenB++;
        curB=curB->next;
    }
    
    //尾结点不相等则不相交
    if(curA!=curB){
        return NULL;
    }
    //相交:找相交位置
    //长度的差距
    int gap=abs(lenA-lenB);  
    
    //先假设长短,再通过if语句修正
    struct ListNode* longList=headA;
    struct ListNode* shortList=headB;
    if(lenA<lenB){
        longList=headB;
        shortList=headA;
        //此时就longList一定代表长链表,shortList一定代表短链表,就不用区分AB了
    }
    //移动差距步gap
    for(int i=0;i<gap;i++){
        longList=longList->next;
    }
    //再逐个比较是否相等,相等的位置即是相交位置起点
    while(longList!=shortList){
        longList=longList->next;
        shortList=shortList->next;
    }
    return longList;
}

你可能感兴趣的:(代码随想录,链表,数据结构)