1. 程式人生 > >leetcode160. Intersection of Two Linked Lists(尋找兩個連結串列的交叉點)

leetcode160. Intersection of Two Linked Lists(尋找兩個連結串列的交叉點)

題目要求 (技巧題)

寫一個程式來實現,自動尋找兩個連結串列的交叉點。如圖:
交叉點是c1
A,B兩個連結串列的交叉點是c1

示例演示

在這裡插入圖片描述

Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
Output: Reference of the node with value = 8
Input Explanation: 輸入的交叉點的值是8(注意如果兩個連結串列交叉,那麼這個值一定不能為0) 
從A的頭開始讀取,A是[4,1,8,4,5]. 
從B的頭開始讀取,B是[
5,0,1,8,4,5]. A中在交叉點之前有兩個結點,B中在交叉點之前有三個結點。

在這裡插入圖片描述

IInput: intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
Output: Reference of the node with value = 2
Input Explanation: 輸入的交叉點的值是2(注意如果兩個連結串列交叉,那麼這個值一定不能為0) 
從A的頭開始讀取,A是[0,9,1,2,4]. 
從B的頭開始讀取,B是[3,2,4]. 
A中在交叉點之前有三個結點,B中在交叉點之前有一個結點。

在這裡插入圖片描述

Input: intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
Output: null
Input Explanation: 
從A的頭開始讀取,A是[2,6,4]. 
從B的頭開始讀取,B是[1,5]. 由於兩個列表沒有交叉,所以交點必須為0.
Explanation: 
兩個表沒有交叉,所以返回空。

解題思路

通過上面例項給出的情況,我們把操作分成三種類型,第一種是有交點且A比B長,第二種是有交點且A比B短,第三種是A,B沒有交點。

接著一個問題,如何去判斷有無交點?
注意:這個交點是指定的,不是有相同的元素值就可以(比如ex1中的1),我們可以理解為當兩個連結串列指向同一個元素時即為相交

根據這種思路,我們想到可以使用指標相等來判斷,分別遍歷兩個連結串列,當兩個指標相等時侯(即指向同一個位置或者同時為空)那麼就能證明兩個連結串列相交(不相交)。

下一個問題,連結串列不同怎麼遍歷判斷?
這裡有一個小技巧,組合A,B兩個連結串列的長度。
當A遍歷完成後,指向B的表頭繼續遍歷。
當B遍歷完成後,指向A的表頭繼續遍歷。
這樣的話,A,B兩個連結串列在長度上就為“一致”了。

主要程式碼c++

/**
 * 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) {
        ListNode *p1 = headA;
        ListNode *p2 = headB;
        while(p1 != p2) 
        //兩種情況指標相等,一個是交點(指向同一個點地址相同),另一種是沒有交點全都指向末尾的空指標
        {
            p1 = p1? p1->next: headB; //遍歷連結串列,若A到尾則移到B的頭部
            p2 = p2? p2->next: headA; //遍歷連結串列,若B到尾則移到A的頭部
        }
        return p1; //返回交點或者空
    }
};

原題連結:https://leetcode.com/problems/intersection-of-two-linked-lists/