美文网首页
Intersection of Two Linked Lists

Intersection of Two Linked Lists

作者: 余启涛 | 来源:发表于2019-03-17 22:50 被阅读0次
    题目一.png
    题目二.png

    解决思路

    思路一

    遍历两个链表到末尾节点,同时分别对两个链表长度计数,判断末尾节点是否相同,相同则说明交叉,将长的链表先移动长度差个节点,同时遍历两个链表,第一个相同节点即为所求。
    注意,可能短链表是长链表的一部分,或者两个链表完全一样。
    example :

    /**
     * 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;
            int cntA=0;
            int cntB=0;
            ListNode* curA=headA;
            ListNode* curB=headB;
            int sub=0;
            while(1)
            {
                if(!curA->next&&!curB->next)
                    break;
                if(curA->next)
                {
                    cntA++;
                    curA=curA->next;
                }
                if(curB->next)
                {
                    cntB++;
                    curB=curB->next;
                }
            }
            if(curA!=curB)
                return NULL;
            curA=headA;
            curB=headB;
            if(cntA>cntB)
            {
                 sub=cntA-cntB;
                 
                 while(sub)
                 {
                     curA=curA->next;
                     sub--;
                 }
    
            }
            else
            {
                sub=cntB-cntA;
                while(sub)
                {
                    curB=curB->next;
                    sub--;
                }
            }
            while(curA!=curB)
            {
                curA=curA->next;
                curB=curB->next;
            }
            return curA;
        }
    };
    

    思路二

    将第一个链表的末尾节点指向第二个节点的头部(返回结果前要拆开),问题转换为求单链表是否有环,环入口即为所求交叉点。
    合并后的单链表头为第一个链表的头,判断是否有环的方式为,定义两个指针,一个slow,每次前进一步,一个fast,每次前进两步,
    直至slow == fast 或者 fast走到末尾,slow==fast说明有环,fast走到末尾说明无环。判断有环后,定义两个指针,一个指向刚才的相遇点,一个指向合并后的链表头,相等即为环入口(两个链表组成一个循环单链表情况),两个指针每次移动一步,直到找到相同点,即为环入口。

    判断环方式,求环入口方法证明略。

    example:

    /**
     * Definition for singly-linked list.
     * type ListNode struct {
     *     Val int
     *     Next *ListNode
     * }
     */
    func getIntersectionNode(headA, headB *ListNode) *ListNode {
        if headA == nil || headB == nil {
            return nil
        }
        
        var last *ListNode
        
        for cur := headA; ; {
            if cur.Next == nil {
                last = cur
                cur.Next = headB
                break
            }
            cur = cur.Next
        }
        
        fast, slow := headA, headA
        find := false
        for ; fast != nil && fast.Next != nil;  {
            slow = slow.Next;
            fast = fast.Next.Next;
            if slow == fast {
                find = true
                break
            }
        }
        if ! find {
            last.Next = nil
            return nil
        }else {
            fast = headA
            for {
                if slow == fast {
                    last.Next = nil
                    return slow
                }
                slow = slow.Next
                fast = fast.Next
            }
        }
    } 
    

    相关文章

      网友评论

          本文标题:Intersection of Two Linked Lists

          本文链接:https://www.haomeiwen.com/subject/eiipmqtx.html