---
# System prepended metadata

title: '#3 160. Intersection of Two Linked Lists'
tags: [leetcode, linked list, easy]

---

# #3 160. Intersection of Two Linked Lists

###### tags:`linked list` `easy` `leetcode`

## Problem
Given the heads of two singly linked-lists `headA` and `headB`, return the node at which the two lists intersect. If the two linked lists have no intersection at all, return `null`.

For example, the following two linked lists begin to intersect at node `c1`:
<br/>

![](https://i.imgur.com/nTgZ7zl.png)

<br/>
The test cases are generated such that there are no cycles anywhere in the entire linked structure.

**Note** that the linked lists must **retain their original structure** after the function returns
<br/>
**Custom Judge:**

The inputs to the **judge** are given as follows (your program is **not** given these inputs):

- `intersectVal` - The value of the node where the intersection occurs. This is 0 if there is no intersected node.
- `listA` - The first linked list.
- `listB` - The second linked list.
- `skipA` - The number of nodes to skip ahead in `listA` (starting from the head) to get to the intersected node.
- `skipB` - The number of nodes to skip ahead in `listB` (starting from the head) to get to the intersected node.

The judge will then create the linked structure based on these inputs and pass the two heads, `headA` and `headB` to your program. If you correctly return the intersected node, then your solution will be **accepted**.

- testcase:
    ```
    8
    [4,1,8,4,5]
    [5,6,1,8,4,5]
    2
    3
    ```





### Sample Input & Output
#### Example 1
![](https://i.imgur.com/EPCXvus.png)

```javascript
Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
Output: Intersected at '8'
Explanation: The intersected node's value is 8 (note that this must not be 0 if the two lists intersect).
From the head of A, it reads as [4,1,8,4,5]. From the head of B, it reads as [5,6,1,8,4,5]. There are 2 nodes before the intersected node in A; There are 3 nodes before the intersected node in B.
```
#### Example 2
![](https://i.imgur.com/ZJJmxMx.png)

```javascript
Input: intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
Output: Intersected at '2'
Explanation: The intersected node's value is 2 (note that this must not be 0 if the two lists intersect).
From the head of A, it reads as [1,9,1,2,4]. From the head of B, it reads as [3,2,4]. There are 3 nodes before the intersected node in A; There are 1 node before the intersected node in B.
```

#### Example 3
![](https://i.imgur.com/eGI2Foo.png)

```javascript
Input: intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
Output: No intersection
Explanation: From the head of A, it reads as [2,6,4]. From the head of B, it reads as [1,5]. Since the two lists do not intersect, intersectVal must be 0, while skipA and skipB can be arbitrary values.

Explanation: The two lists do not intersect, so return null.
```

### Constraints
- `intersectVal == listA[skipA] == listB[skipB]` if `listA` and `listB` intersect.

### Follow up
Could you write a solution that runs in `O(m + n)` time and use only `O(1)` memory?

<br>

## Solutions

### Official 
none.
<br>

---

### Everyone's
#### solution 1: record the nodes

:::spoiler 月
```javascript=
var getIntersectionNode = function(headA, headB) {
    // Time O(a+b) Space O(a)
    // a is the length of headA; b is the length of headB
    
    const recordSet = new Set();
    // set headA node in recordSet
    while(headA) {
        recordSet.add(headA);
        headA = headA.next;
    }
    while(headB) {
        if (recordSet.has(headB)) {
            return headB;
        }
        headB = headB.next;
    }
    return null;
};
```
:::

<br>

#### solution 2: truncate the list

:::spoiler 東
```javascript=
// Time O(m+n), Space O(m+n) m, n is the amount of node of input headA, headB
var getIntersectionNode = function(headA, headB) {
    let listA = headA;
    let listB = headB;
    const lenA = calculateLength(headA);
    const lenB = calculateLength(headB);
    
    if(lenA > lenB){
        const AStartIdx = lenA - lenB;
        listA = moveListToIdx(listA, AStartIdx);
    } else{
        const BStartIdx = lenB - lenA;
        listB = moveListToIdx(listB, BStartIdx);
    }
    
    while(listA !== null){
        if(listA === listB){
            return listA;
        }
        listA = listA.next;
        listB = listB.next;
    }
    return null;
};

function calculateLength(list){
    let count = 0;
    while(list !== null){
        count ++;
        list = list.next;
    }
    return count;
}
    
function moveListToIdx(list, idx){
    while(idx > 0){
        list = list.next;
        idx --;
    }
    return list;
}
```
:::
<br/>

#### solution 3: loop the list
:::spoiler Raiy
```javascript=
var getIntersectionNode = function(headA, headB) {
    // time: O(n+m)? space: O(1) n = headA length, m = headB length 
    // -> time: O(n*m) : the worst case
   if(!headA || !headB) return null
    
   let currentA = headA
   let currentB = headB
   
   while(currentA !== currentB){
       currentA = currentA.next
       currentB = currentB.next
       
       if(currentA === currentB){
           return currentA
       }
     
       if(!currentA) currentA = headA
       if(!currentB) currentB = headB
   }

    
    return currentA
};
```
:::

<br>

#### solution 4: concatenate two lists

:::spoiler YC
```javascript=
/*
 * time: O(m+n), where m is the number of nodes in the headA, n is the number of nodes in the headB 
 * space: O(1)
 */
var getIntersectionNode = function(headA, headB) {
    let listA = headA;
    let listB = headB;
    while(listA !== listB){
        listA = listA === null ? headB : listA.next;
        listB = listB === null ? headA : listB.next;
    }
    return listA;
};
```
:::



:::spoiler Becky
```javascript=
//time: O(n) | space: O(1)
//-> time: O(m+n)
var getIntersectionNode = function(headA, headB) {
    let a = headA;
    let b = headB;
    
    while (a != b) {
        if(a === null){
            a = headB;
        }else{
            a = a.next;
        }

        if(b === null){
            b = headA;
        }else{
            b = b.next
        }
    }
    
    return a;
};
```
:::

<br>

<br>

#### backlog




:::spoiler Hao
```javascript=

```
:::

<br>


:::spoiler SOL
```javascript=

```
:::

---

## Supplement / Discussion
![](https://i.imgur.com/3bY6kiv.png)
(示意圖)

### Thinking 1
直觀的做法：把 A 的 node 存起來，遍歷 B 找重複的點

### Thinking 2
直觀的做法：既然 B 比 A 長，那就讓 B 從 b2 開始判斷。
> 計算 A, B 的總長，取差值 `B - A`，loop 找出 c1
```
A:     a1  c1  c2
 
B: b1  b2  c1  c2

⬇️

A:     a1  c1  c2
 
B:     b2  c1  c2

```

### Thinking 3
如果 A 和 B 同時從頭開始尋找相交的點，會在什麼時候找到 c1
> list 不斷重複自己
```
A: a1  c1  c2| a1  c1  c2| a1  c1  c2| a1  c1  c2
 
B: b1  b2  c1  c2| b1  b2  c1  c2| b1  b2  c1  c2 
```
在 A 重複自己四次、B 重複自己三次後，找到 c1 了

:::info
有發現什麼有趣的現象嗎？
:::

### Thinking 4
:::info
從 Thinking 3 可以發現，出現相交的點後，A 和 B 最後的長度會一樣長。
:::

還有其他方法可以讓兩者的長度一樣嗎？
> A + B = B + A

:::spoiler 回頭看看 Follow up
Could you write a solution that runs in `O(m + n)` time and use only `O(1)` memory?
:::
<br/>

```
A: a1  c1  c2
 
B: b1  b2  c1  c2

⬇️

A + B: a1  c1  c2| b1  b2  c1  c2

B + A: b1  b2  c1  c2| a1  c1  c2
```
