0
点赞
收藏
分享

微信扫一扫

链表相交

判断链表是否有环,若有,返回第一个入环节点,若无,返回空。

快慢指针,若无环,快指针走到空,若有环,快慢指针相遇,然后快指针原地不动,慢指针回到头节点,快慢指针每次各走一步,相遇的节点为入环节点。

class Solution {
public:
    ListNode *getLoopNode(ListNode *head){
        ListNode *slow = head;
        ListNode *fast = head;
        while(slow && fast){
            slow = slow -> next;
            fast = (fast -> next) ? fast -> next -> next : nullptr;
            if(slow == fast){
                break;
            }
        }
        if(slow == nullptr || fast == nullptr){
            return nullptr;
        }
        slow = head;
        while(slow != fast){
            slow = slow -> next;
            fast = fast -> next;
        }
        return slow;
    }
};

【题目】给定两个可能有环也可能无环的单链表,头结点head1和head2.请实现一个函数,如果两个链表相交,请返回相交的第一个节点。如果不想交,返回null。

【要求】如果两个链表长度之和为N,时间复杂度请达到O(N),额外空间复杂度请达到O(1)。

使用getNodeLoop函数判断两个链表是否有环:

1)均无环:先计算两链表长度,长度差值为n,随后长链表先走n步,随后两链表同步移动,当移动到同一节点时,即为相交的第一个节点,若移动到null,两链表不相交。

2)一个有环一个无环:必不相交

3)均有环:

链表相交_链表


设getNodeLoop函数返回的两个节点指针为n1,n2.

若n1 n2指向相同的内存地址,则为情况2.

否则,让n1移动一圈回到n1,如果中途遇到n2,则为情况3,否则为情况1.

情况2找首个相交节点:把n1(也是n2)作为链表末尾,转化为找无环相交链表的首个相交节点。

情况3:返回n1/n2均可。

class Solution {
public:
    ListNode *getLoopNode(ListNode *head){
        ListNode *slow = head;
        ListNode *fast = head;
        while(slow && fast){
            slow = slow -> next;
            fast = (fast -> next) ? fast -> next -> next : nullptr;
            if(slow == fast){
                break;
            }
        }
        if(slow == nullptr || fast == nullptr){
            return nullptr;
        }
        slow = head;
        while(slow != fast){
            slow = slow -> next;
            fast = fast -> next;
        }
        return slow;
    }

    ListNode* noLoop(ListNode *head1, ListNode *head2){
        if(head1 == nullptr || head2 == nullptr){
            return nullptr;
        }
        ListNode *cur1 = head1;
        ListNode *cur2 = head2;
        int n = 0;
        while(cur1 -> next){
            n++;
            cur1 = cur1 -> next;
        }
        while(cur2 -> next){
            n--;
            cur2 = cur2 -> next;
        }
        if(cur1 != cur2){
            return nullptr;
        }
        cur1 = n > 0 ? head1 : head2;
        cur2 = cur1 == head1 ? head2 : head1;
        n = n > 0 ? n : -n;
        while(n != 0){
            n--;
            cur1 = cur1 -> next;
        }
        while(cur1 != cur2){
            cur1 = cur1 -> next;
            cur2 = cur2 -> next;
        }
        return cur1;
    }

    ListNode* bothLoop(ListNode *head1, ListNode *loop1, ListNode *head2, ListNode *loop2){
        if(loop1 == loop2){
            ListNode *cur1 = head1;
            ListNode *cur2 = head2;
            int n = 0;
            while(cur1 != loop1){
                n++;
                cur1 = cur1 -> next;
            }
            while(cur2 != loop2){
                n--;
                cur2 = cur2 -> next;
            }
            cur1 = n > 0 ? head1 : head2;
            cur2 = cur1 == head1 ? head2 : head1;
            n = n > 0 ? n : -n;
            while(n != 0){
                cur1 = cur1 -> next;
                n--;
            }
            while(cur1 != cur2){
                cur1 = cur1 -> next;
                cur2 = cur2 -> next;
            }
            return cur1;
        }
        else{
            ListNode *cur = loop1 -> next;
            while(cur != loop1){
                if(cur == loop2){
                    return loop1;
                }
                cur = cur -> next;
            }
            return nullptr;
        }
    }

    ListNode* getIntersectNode(ListNode *head1, ListNode *head2){
        if(head1 == nullptr || head2 == nullptr){
            return nullptr;
        }
        ListNode *loop1 = getLoopNode(head1);
        ListNode *loop2 = getLoopNode(head2);
        if(loop1 == nullptr && loop2 == nullptr){
            return noLoop(head1, head2);
        }
        if(loop1 != nullptr && loop2 != nullptr){
            return bothLoop(head1, loop1, head2, loop2);
        }
        return nullptr;
    }
};


举报

相关推荐

0 条评论