Study(진행중)/항해99
99클럽 코테 스터디 35일차 TIL + 표 병합(프로그래머스)
Ski_
2024. 8. 26. 00:16
오늘의 학습 키워드
- 구현
- union-find
공부한 내용 본인의 언어로 정리하기
https://school.programmers.co.kr/learn/courses/30/lessons/150366
여러 구현 방법이 있겠지만, union-find를 활용한 문제를 풀었따.
풀이 과정은 다음과 같다.
1. UPDATE r c value
- r행c열의 부모를 find 연산으로 찾은 뒤 update
2. UPDATE value1 value2
- 모든 셀을 돌며 value1과 동일한 값들을 value2로 변경
3. MERGE r1 c1 r2 c2
- r1, c1의 부모와 r2 c2의 부모를 find 연산으로 찾은 뒤 union(r1c1, r2c2)
4. UNMERGE r c
- r c의 부모를 find 연산으로 찾은 뒤, 모든 셀을 돌며 부모가 동일한 경우 초기화
5. PRINT r c
- r c 의 부모가 가진 값을 출력
풀이는 다음과 같다.
import java.util.*;
class Solution {
class Cell {
int r, c, idx;
String value;
Cell(int idx, int r, int c) {
this.idx = idx; this.r = r; this.c = c;
}
}
int[] parents;
Cell[] map;
public String[] solution(String[] commands) {
parents = new int[2501];
map = new Cell[2501];
int idx = 1;
for (int i = 1; i <= 50; i++) {
for (int j = 1; j <= 50; j++, idx++) {
map[idx] = new Cell(idx, i, j);
parents[idx] = idx;
}
}
List<String> ans = new ArrayList<>();
StringTokenizer st;
for (String command : commands) {
st = new StringTokenizer(command);
String cmd = st.nextToken();
int r, c, parent;
String value;
switch(cmd) {
case "UPDATE":
String value1 = st.nextToken();
String value2 = st.nextToken();
if (st.hasMoreTokens()) {
value = st.nextToken();
r = Integer.parseInt(value1);
c = Integer.parseInt(value2);
parent = find(toIdx(r, c));
map[parent].value = value;
} else {
for (int i = 1; i <= 2500; i++) {
if (Objects.equals(map[i].value, value1))
map[i].value = value2;
}
}
break;
case "MERGE":
int r1 = Integer.parseInt(st.nextToken());
int c1 = Integer.parseInt(st.nextToken());
int r2 = Integer.parseInt(st.nextToken());
int c2 = Integer.parseInt(st.nextToken());
int parentA = find(toIdx(r1, c1));
int parentB = find(toIdx(r2, c2));
union(parentA, parentB);
break;
case "UNMERGE":
r = Integer.parseInt(st.nextToken());
c = Integer.parseInt(st.nextToken());
idx = toIdx(r, c);
parent = find(idx);
value = map[parent].value;
List<Integer> clearList = new ArrayList<>();
for (int i = 1; i <= 2500; i++) {
if (find(i) == parent) {
clearList.add(i);
}
}
for (int i : clearList) {
parents[i] = i;
map[i].value = null;
}
map[idx].value = value;
break;
case "PRINT":
r = Integer.parseInt(st.nextToken());
c = Integer.parseInt(st.nextToken());
idx = toIdx(r, c);
parent = find(idx);
value = map[parent].value;
if (value == null) ans.add("EMPTY");
else ans.add(value);
break;
}
}
String[] answer = new String[ans.size()];
for (int i = 0; i < ans.size(); i++) answer[i] = ans.get(i);
return answer;
}
boolean union(int a, int b) {
int parentA = find(a);
int parentB = find(b);
if (parentA == parentB) return false;
String valueA = map[parentA].value;
String valueB = map[parentB].value;
if (valueA == null) parents[parentA] = parentB;
else parents[parentB] = parentA;
return true;
}
int find(int idx) {
if (parents[idx] == idx) return idx;
return parents[idx] = find(parents[idx]);
}
int toIdx(int r, int c) {
return (r - 1) * 50 + c;
}
}
반응형