알고리즘 체조 12
10610 단어 자바LinkedListalgorithmHashSet
Intersection Point of Two Lists
설명
두 개의 링크 된 목록의 머리가 전달되므로 두 개의 링크 된 목록이 실제로 교차하는지 확인하고,
그 교차로를 반환하는 알고리즘을 구현해 봅시다. 교차점이 없으면 null을 반환합니다.
교차점이라고 하는 것은 Node의 메모리에 있는 주소가 동일하다는 것을 의미합니다.
다음 예제에서는 두 목록 모두 교차하지 않습니다.
다음 예제에서는 교차점인 12개의 데이터를 보유하는 노드가 있으므로 해당 노드를 반환합니다.
Solution1
우선, 최초로 생각하는 구현의 방법은 첫 번째의 Linked List의 노드가 두 번째의 Linked List에도 존재하는가
실행 시간이 O(m * n)의 효율이 나쁜 알고리즘입니다 (m와 n은 Linked List의 길이).
이 경우 런타임은 느리지만 Space Complexity는 두 개의 포인터를 사용하여 스캔하기 때문에 O (1)입니다.
Solution2
다만, 메모리에 여유가 있어 실행 시간을 보다 효율적으로 향상시키고 싶다고 합시다. 이 경우 먼저 머리에 떠오르는 것은
HashTable을 사용한 데이터 구조를 사용하는 것입니다. 그래서 Java의 HashSet을 사용하여 구현합니다.
우선 하나의 Linked List의 요소를 선형 주사하면서 HashSet에 Node를 추가해 갑니다.
그런 다음 두 번째 링크 된 목록에 대해 선형 스캔하면서 HashSet에 동일한 노드가 있는지 확인합니다.
HashSet의 요소에의 액세스는 물론 O(1)이므로, 이 구현의 실행 시간은 O(m + n)가 되어, 효율 좋게 되었습니다.
구현
Intersect.javaclass Intersect{
public LinkedListNode findintersect(LinkedListNode head1,LinkedListNode head2) {
LinkedListNode cur1 = head1;
LinkedListNode cur2 = head2;
LinkedListNode interSectionNode = null;
HashSet<LinkedListNode> hashSet = new HashSet<>();
while (cur1 != null) {
hashSet.add(cur1);
cur1 = cur1.next;
}
while (cur2 != null) {
if (hashSet.contains(cur2)) {
interSectionNode = cur2;
break;
}
cur2 = cur2.next;
}
return interSectionNode;
}
}
Solution3
이제 링크된 목록에 엄청난 양의 데이터가 있다고 가정하여 좀 더 메모리 효율성을 향상시킬 수 없는지 생각해 봅시다.
먼저 두 링크된 목록이 같은 크기라고 가정해 봅시다.
이 경우 두 맨 위에서 서로 다른 두 포인터를 사용하여 노드의 주소를 비교할 수 있습니다.
이 주소가 일치하면 교차로임을 의미합니다.
일치하지 않으면 두 포인터를 동시에 하나씩 이동하여 주소를 비교합니다.
교차점이 발견되거나 두 목록이 모두 없어질 때까지 이 과정을 반복합니다.
이제 목록의 길이가 다른 경우 문제를이 개념을 사용해 보겠습니다.
class Intersect{
public LinkedListNode findintersect(LinkedListNode head1,LinkedListNode head2) {
LinkedListNode cur1 = head1;
LinkedListNode cur2 = head2;
LinkedListNode interSectionNode = null;
HashSet<LinkedListNode> hashSet = new HashSet<>();
while (cur1 != null) {
hashSet.add(cur1);
cur1 = cur1.next;
}
while (cur2 != null) {
if (hashSet.contains(cur2)) {
interSectionNode = cur2;
break;
}
cur2 = cur2.next;
}
return interSectionNode;
}
}
이 알고리즘이라면, 실행 시간은 O(n + m) 그대로, 메모리의 효율을 O(1)로 할 수 있습니다.
예
구현
Intersect.java
class Intersect{
public LinkedListNode findIntersect(LinkedListNode head1,LinkedListNode head2) {
LinkedListNode list1node = null;
int list1length = getLength(head1);
LinkedListNode list2node = null;
int list2length = getLength(head2);
int length_difference = 0;
if(list1length >= list2length) {
length_difference = list1length - list2length;
list1node = head1;
list2node = head2;
} else {
length_difference = list2length - list1length;
list1node = head2;
list2node = head1;
}
while(length_difference > 0) {
list1node = list1node.next;
length_difference--;
}
while(list1node != null) {
if(list1node == list2node) {
return list1node;
}
list1node = list1node.next;
list2node = list2node.next;
}
return null;
}
private int getLength(
LinkedListNode head) {
int list_length = 0;
while(head != null) {
head = head.next;
list_length++;
}
return list_length;
}
}
Reference
이 문제에 관하여(알고리즘 체조 12), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/yutakihara/items/0d66c3b395429abf747e텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)