Intersection of Two Linked Lists
문제 설명
- 두 개의 단방향 연결 리스트 headA와 headB가 주어집니다.
- 두 리스트가 어떤 위치에서든 교차할 수 있습니다. 즉, 특정 노드 이후부터 두 리스트가 동일한 노드들을 공유하게 될 수 있습니다.
- 이 문제에서 교차점이란 두 리스트가 연결되어 동일한 노드들이 뒤따르는 시작 지점을 의미합니다.
- 교차점이 없는 경우 null을 반환합니다.
예시
1. 예제1
1) 입력 : headA = [4,1,8,4,5], headB = [5, 6, 1, 8, 4, 5]
2) 출력: 교차 노드 값이 8
2. 예제2
1) 입력: headA = [2,6,4], headB = [1,5]
2) 출력: null (교차 없음)
해결방법
투 포인터를 사용합니다.
1. 포인터 설정
1) 포인터 nodeA를 리스트 headA의 시작 지점에 두고, 포인터 nodeB를 리스트 headB의 시작 지점에 둡니다.
2. 포인터 이동
1) 두 포인터가 각각 headA와 headB를 끝까지 순회한 뒤에도 교차점이 발견되지 않았다면, 투 포인터를 서로 반대 리스트의 시작 지점으로 이동합니다.
2) 즉, nodeA가 headA의 끝에 도달하면 nodeB의 시작으로, nodeB가 headB의 끝에 도달하면 nodeA의 시작으로 이동하게 합니다.
3. 교차점 발견
1) 투 포인터가 교차점에서 만나게 되면 해당 위치의 노드를 반환합니다.
2) 만약 끝까지 탐색해도 투 포인터가 만나지 않는다면 교차점이 없다는 뜻이므로 null을 반환합니다.
코드
package easy.intersectionOfTwoLinkedList;
public class Solution {
public static class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) return null;
ListNode nodeA = headA;
ListNode nodeB = headB;
while (nodeA != nodeB) {
nodeA = (nodeA == null) ? headB : nodeA.next;
nodeB = (nodeB == null) ? headA : nodeB.next;
}
return nodeA;
}
public static void main(String[] args) {
// 교차 노드를 생성합니다.
ListNode intersection = new ListNode(8);
intersection.next = new ListNode(4);
intersection.next.next = new ListNode(5);
// listA를 생성하고 교차 노드에 연결합니다.
ListNode listA = new ListNode(4);
listA.next = new ListNode(1);
listA.next.next = intersection;
// listB를 생성하고 교차 노드에 연결합니다.
ListNode listB = new ListNode(5);
listB.next = new ListNode(6);
listB.next.next = new ListNode(1);
listB.next.next.next = intersection;
Solution solution = new Solution();
ListNode node = solution.getIntersectionNode(listA, listB);
System.out.println(node != null ? node.val : "No intersection");
}
}
예시1 테이블
포인터 | 1단계 | 2단계 | 3단계 | 4단계 | 5단계 | 6단계 | 7단계 | 8단계 | 9단계 | 10단계 |
---|---|---|---|---|---|---|---|---|---|---|
nodeA |
4 | 1 | 8 | 4 | 5 | null |
5 | 6 | 1 | 8 |
nodeB |
5 | 6 | 1 | 8 | 4 | 5 | null |
4 | 1 | 8 |
설명
- 1단계:
nodeA
는listA
의 첫 번째 노드4
,nodeB
는listB
의 첫 번째 노드5
를 가리킵니다. - 2단계:
nodeA
는1
,nodeB
는6
을 가리킵니다. - 3단계:
nodeA
는8
,nodeB
는1
을 가리킵니다. - 4단계:
nodeA
는4
,nodeB
는8
을 가리킵니다. - 5단계:
nodeA
는5
,nodeB
는4
를 가리킵니다. - 6단계:
nodeA
가listA
의 끝에 도달하여null
이 되고,nodeB
는5
를 가리킵니다. - 7단계:
nodeA
는listB
의 시작으로 이동하여5
를 가리키고,nodeB
는null
이 됩니다. - 8단계:
nodeA
는6
,nodeB
는listA
의 시작으로 이동하여4
를 가리킵니다. - 9단계:
nodeA
는1
,nodeB
는1
을 가리킵니다.(값이 동일해도, 객체가 동일하지 않음) - 10단계:
nodeA
와nodeB
가8
에서 만나므로, 교차점을 찾게 되어 탐색이 종료됩니다.
이제 교차점 노드 8
에서 두 포인터가 만나므로, 이 노드가 두 리스트의 교차점입니다.
예시2 테이블
포인터 | 1단계 | 2단계 | 3단계 | 4단계 | 5단계 | 6단계 | 7단계 |
---|---|---|---|---|---|---|---|
nodeA |
2 | 6 | 4 | null |
1 | 5 | null |
nodeB |
1 | 5 | null |
2 | 6 | 4 | null |
설명
- 1단계:
nodeA
는listA
의 첫 번째 노드2
를 가리키고,nodeB
는listB
의 첫 번째 노드1
을 가리킵니다. - 2단계:
nodeA
와nodeB
모두 각각 다음 노드로 이동하여nodeA
는6
,nodeB
는5
를 가리킵니다. - 3단계:
nodeA
는4
로 이동하고,nodeB
는listB
의 끝에 도달하여null
이 됩니다. - 4단계:
nodeA
가null
이 되어listB
의 시작2
로 이동하고,nodeB
는listA
의 시작2
로 이동합니다. - 5단계:
nodeA
는6
,nodeB
는6
으로 다음 노드로 이동합니다. - 6단계:
nodeA
와nodeB
모두 각각 다음 노드로 이동하여nodeA
는5
,nodeB
는4
를 가리킵니다. - 7단계:
nodeA
와nodeB
는 동시에null
이 되어 종료됩니다.
이제 두 포인터가 동시에 null
에 도달하여 교차점이 없음을 확인하게 됩니다.
'여러가지 > 알고리즘 & 자료구조' 카테고리의 다른 글
[프로그래머스] 문자열 내마음대로 정렬하기 (3) | 2024.10.16 |
---|---|
[프로그래머스] 푸드 파이트 대회 (1) | 2024.10.16 |
[프로그래머스] k번째수 (0) | 2024.10.16 |
[프로그래머스] 숫자 문자열과 영단어 (0) | 2024.10.16 |
[프로그래머스] 가장 가까운 같은 글자 (0) | 2024.10.16 |