파인드(find) 문제입니다.
문제를 요약하면 '같은 집합을 이루는 배열의 원소 개수를 찾아 가장 큰 두 개를 곱하라' 입니다.
입력의 각 원소는 자신과 같은 집합을 이루는 위치를 가르키고 있습니다.
즉, 이미 유니온(union)이 되어있는 집합이 입력으로 주어지는 것입니다.
각 위치에서 find연산을 통해 어느 집합에 속하는지 파악하면 끝나는 문제입니다.
단, 주의해햐할 점이 있습니다.
입력으로 주어지는 배열은 순환을 발생시킬 수 있기 때문에 이미 방문한 곳은 재방문하지 않도록 하면 됩니다.
find 연산을 할 때, 최상위 부모를 저장시켜 방문한 곳은 값을 확인하면 됩니다.
[구현 코드]
import java.util.*;
class Solution {
int[] parents;
public int solution(int[] cards) {
int answer = 0;
parents = cards;
int n = cards.length;
Map<Integer, Integer> counts = new HashMap<>();
for(int i=0; i<n; i++){
parents[i]--;
}
boolean[] visited = new boolean[n];
for(int i=0; i<n; i++){
int num = 0;
if(!visited[i]){
num = find(i, visited);
}else{
num = parents[i];
}
counts.put(num, counts.getOrDefault(num, 0) + 1);
}
if(counts.size() < 2){
answer = 0;
}else{
List<Integer> vals = new ArrayList<>();
for(int v : counts.values()){
vals.add(v);
}
vals.sort((o1, o2) -> o2-o1);
answer = (vals.get(0) * vals.get(1));
}
return answer;
}
int find(int a, boolean[] visited){
if(a == parents[a] || visited[a]){
return a;
}
visited[a] = true;
// find연산을 하되, 최상위 부모를 저장하도록 함
return parents[a] = find(parents[a], visited);
}
}
'알고리즘' 카테고리의 다른 글
백준 - 11501 주식(Java) (0) | 2023.04.13 |
---|---|
프로그래머스 - 연속된 부분 수열의 합(Java) (2) | 2023.04.09 |
프로그래머스 - 연속 펄스 부분 수열의 합(Java) (0) | 2023.03.29 |
백준 - 5052 전화번호 목록(Java) (0) | 2023.03.28 |
백준 - 20166 문자열 지옥에 빠진 호석(Java) (0) | 2023.03.28 |