https://school.programmers.co.kr/learn/courses/30/lessons/388354
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr

코드 :
import java.util.*;
class Solution {
List<Integer>[] adj;
Set<Integer> visited = new HashSet<>(); // 방문체크
Map<Integer, List<Integer>> groupMap = new HashMap<>(); // groupNo -> nodes
public static final int FORWARD_TREE = 0; // 홀짝트리
public static final int REVERSE_TREE = 1; // 역홀짝트리
int yellow = 0;
int red = 0;
public int[] solution(int[] nodes, int[][] edges) {
int[] answer = new int[2];
int n = 1_000_000;
adj = new ArrayList[n + 1];
for (int i = 0; i <= n; i++) adj[i] = new ArrayList<>();
for (int[] edge : edges) {
adj[edge[0]].add(edge[1]);
adj[edge[1]].add(edge[0]);
}
for (int root : nodes) {
yellow = 0; red = 0;
searchGroup(root);
// yello 1개 -> 모두 red로 만들 수 있음 -> 역홀짝
if (yellow == 1) {
answer[REVERSE_TREE]++;
}
// red 1개 -> 모두 yellow -> 홀짝
if (red == 1) {
answer[FORWARD_TREE]++;
}
}
return answer;
}
// 해당 노드가 속한 그룹의 색깔을 카운트
private void searchGroup(int now) {
if (visited.contains(now)) {
return;
}
visited.add(now);
// 루트가 아닐때의 각 노드 색깔
boolean isYellowWhenNotRoot = (now % 2 == (adj[now].size() - 1) % 2);
if (isYellowWhenNotRoot) yellow++;
else red++;
for (int next : adj[now]) {
searchGroup(next);
}
}
}
풀이 :
- 문제의 예시를 참고하여 홀짝노드는 Y(Yellow), 역홀짝노드는 R(Red)로 표현하겠습니다. 트리(그룹)별로 모든 노드의 색이 Y 혹은 R인 경우를 찾아야합니다.
- 특정 노드를 루트노드로 지정한다면, 값은 그대로지만 자식노드가 +1 됩니다.
- (노드 -> 루트노드)로 변경 시, 원래 홀짝 노드였다면 역홀짝으로(Y->R), 원래 역홀짝이었다면 홀짝(R->Y)로 변경됩니다.
- 그 반대도 같습니다. (루트노드 -> 노드)로 변경시 Y->R, R->Y로 바뀝니다.
- 그렇기때문에, 그룹별로 "모든 노드가 루트아닌 노드라고 가정"하고, 각 노드가 Y인지 R인지 판별했을 때, 딱 하나의 노드만 다른 색이라면, 해당 노드를 루트 노드로 지정했을때 모든 노드의 색깔이 같아집니다.
- ex) 특정 그룹의 노드 색깔(루트 아닌 상태) = [Y, R, R, R, R];
- 여기서 첫번째 노드를 루트로 지정하면, [R, R, R, R, R]이 됩니다.
- 주어진 입력에 nodes의 길이가 1일때, 2일때를 주의해야합니다.
요약
- 1) 인접리스트 초기화
- 2) 그룹별로 "모든 노드가 루트아닌 노드라고 가정"하고, 해당 그룹의 색깔이 Y인 노드 개수(yellow), R인 노드 개수(red)를 카운트
- 3) 1개만 다른 색깔인 경우, 혼자 다른 색깔을 가진 노드를 루트로 지정하면 홀짝/역홀짝 중 하나가 되므로 알맞게 카운트해준다.
'알고리즘' 카테고리의 다른 글
LeetCode - First Bad Version (0) | 2022.09.11 |
---|
댓글