삼성전자 코딩테스트 — 자주 나오는 구현 모듈 (Java) 정리
📅 삼성 코테 준비하면서 반복적으로 등장하는 구현 모듈들을 Java 로 정리. 코드트리의 삼성 기출을 기준으로 작성.
참고: 코드트리 — 삼성 기출 모음
1. 회전시키기 — 90° 회전 (시계 / 반시계)
코드트리의 메이즈러너 · 예술성 문제에서 일부 좌표를 90° 회전해야 한다.
⚠️ 전체 격자가 아니라 부분 영역 회전이 나오는 게 핵심. start/end 좌표를 기준으로 상대 좌표를 잡아야 함.
int N = 5;
int[][] map = new int[N][N];
for (int i = 0; i < 5; i++) {
map[i][0] = 1;
}
// 기존 map 이 있다고 가정.
int start_x = 0, end_x = N;
int start_y = 0, end_y = N;
// 90° 시계방향 회전
int[][] newMap = new int[N][N];
for (int i = start_x; i < end_x; i++) {
for (int j = start_y; j < end_y; j++) {
newMap[start_x + (j - start_y)][(end_y - 1) - (i - start_x)] = map[i][j];
}
}
반시계 방향은 인덱스 swap 패턴만 반대로:
newMap[(end_x - 1) - (j - start_y)][start_y + (i - start_x)] = map[i][j];
2. Periodic Boundary Condition (주기 경계)
경계를 넘어가는 순간 그 다음 경계로 wrap-around. 코드트리 '포탑 부수기' 문제.
⚠️ index 를 0 부터 잡느냐 1 부터 잡느냐로 식이 달라진다.
1칸씩 step-by-step
// 0 ~ N-1 indexing
int new_x = (N + (x + dx[dir])) % N;
int new_y = (M + (y + dy[dir])) % M;
// 1 ~ N indexing (밖에 1을 더해주고 내부에서 1을 빼준다)
int new_x = (N + ((x - 1) + dx[dir])) % N + 1;
int new_y = (M + ((y - 1) + dy[dir])) % M + 1;
한 번에 크게 움직임
int distance = 150000000;
// 0 ~ N-1 indexing
int new_x = Math.abs((N + (x + distance))) % N;
int new_y = Math.abs((M + (y + distance))) % M;
// 1 ~ N indexing
int new_x = Math.abs((N + ((x - 1) + distance))) % N + 1;
int new_y = Math.abs((M + ((y - 1) + distance))) % M + 1;
Math.abs안 쓰면 음수 좌표 들어왔을 때 깨짐. 음수 처리 + N 더해서 양수 만들고 mod 패턴.
3. 방향 거꾸로 바꾸는 문제
대표적으로 '주사위 문제 3' · '토끼와 경주' 가 있다. 이 부분은 이해 후 암기가 필요하다 — 방향 인덱스 매핑이 문제마다 살짝 다름.
주사위는 6 면 각각의 회전 후 윗면·아랫면 매핑이 정해져 있고, 토끼 경주는 격자 위 방향 dir 의 반대 방향이
(dir + 2) % 4같은 패턴.
4. Sort — 다중 조건
최근 빈번하게 4–5 개 조건 으로 정렬 문제가 출제됨.
Integer — 표준 Comparator
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) { // 양수면 swap, 음수면 유지
if (o1 < o2) return 1; // 내림차순
else if (o1 == o2) return 0;
else return -1;
}
});
더 간단하게:
return o1 - o2;(오름차순) 또는return o2 - o1;(내림차순).
Long type — compareTo 권장
⚠️ Long 은 직접 빼면 overflow 위험.
compareTo사용.
List<Long> list2 = new ArrayList<>(Arrays.asList(1L, 30L, 0L, 0L, 1L, 3L, 2L, 1L, 0L, 5L));
Collections.sort(list2, new Comparator<Long>() {
@Override
public int compare(Long o1, Long o2) {
if (o1 == 0) {
if (o2 == 0) return 0;
else return 1; // o1 만 0 → 뒤로
} else if (o2 == 0) {
return -1; // o2 만 0 → 뒤로
} else {
return o1.compareTo(o2);
}
}
});
다중 조건 — 우선순위로 chain
Collections.sort(list, (a, b) -> {
if (a.cond1 != b.cond1) return a.cond1 - b.cond1; // 1순위
if (a.cond2 != b.cond2) return b.cond2 - a.cond2; // 2순위 역순
return a.cond3 - b.cond3; // 3순위
});
6. BFS — 최단거리
최단거리 문제는 대부분 BFS. Trace (경로) 까지 가져와야 할 때는 parent[] 배열 필요. 코드트리 '포탑 부수기' 가 대표.
⚠️ 일반 BFS 와 다른 점은 보통 Queue 에 (좌표, 거리) 만 넣지만, trace 필요 시 prev 좌표 도 함께 저장하거나 별도
parent[][]로 추적.
7. Spiral — 나선형 좌표 + 방향 저장
백준 '상어와 블리자드', 코드트리 '스톰'.
⚠️ 단순히 좌표만 저장하면 안 되고, 방향 (dir, rDir) 도 같이 저장해야 하는 경우가 많음.
static void makeSpiral() {
int[] dx = {0, 1, 0, -1};
int[] dy = {-1, 0, 1, 0};
int index = 0;
int dir = 0, rDir = 2;
int cur_depth = 0;
int ref_depth = 1;
int turn = 0;
int x_0 = N / 2;
int y_0 = N / 2;
spiralMap.put(index, new Node(x_0, y_0, dir, rDir));
while (true) {
index++;
if (index == N * N) break;
int new_x = x_0 + dx[dir];
int new_y = y_0 + dy[dir];
spiralMap.put(index, new Node(new_x, new_y, dir, rDir));
cur_depth++;
if (cur_depth == ref_depth) {
dir = (dir + 1) % 4;
rDir = (dir + 2) % 4;
cur_depth = 0;
turn++;
spiralMap.put(index, new Node(new_x, new_y, dir, rDir));
if (turn == 2) {
ref_depth++;
turn = 0;
}
}
x_0 = new_x;
y_0 = new_y;
}
}
핵심: 두 번 방향 전환마다 ref_depth 가 1씩 증가. (1, 1, 2, 2, 3, 3, 4, 4, ...) 패턴.
내가 빠진 함정 — 3 종
함정 1 — 전역 조건 vs 국부 조건
문제 읽을 때 가장 조심해야 할 부분. 어떤 조건이 시뮬레이션 전체에 적용되는지, 국부적으로만 해당하는지 확실히.
예시: - '포탑 부수기': 시계열에 따라 최근 공격한 포탑 vs 공격한 횟수 혼동. - '토끼와 경주': K 번 돌아가는 조건 내에서 한 번이라도 점프한 토끼 ↔ 전체 시뮬에서 한 번이라도 점프한 토끼 잘못 해석.
함정 2 — 동시성 문제 (List.remove + for loop)
List 에서 remove 하면서 for loop 돌리면 하나 건너뛰게 됨. 이 경우 remove 후
i--해서 동시성 해결.
for (int i = 0; i < list.size(); i++) {
if (조건) {
list.remove(i);
i--; // ← 건너뛰는 인덱스 보정
}
}
예시: [1, 2, 3, 4, 5] → index 2 일 때 3 remove → [1, 2, 4, 5] 가 되지만 다음 index 가 3 이 되어 4 가 아닌 5 를 가리키게 됨.
'숨바꼭질' 문제에서도
i--안 해서 동시성 문제 발생.
함정 3 — Loop 빠질 때 break
'꼬리잡기' 문제 — 머리가 다음 갈 곳을 찾을 때 4 방향 탐색. 목표를 찾고 break 하지 않으면 이상한 값으로 덮어 씌워짐.
4 3 2 1 4 3 2 1 4 3 2 2 4 3 3 2 4 4 3 2
4 0 0 4 → 4 0 0 1 → 4 0 0 1 → 4 0 0 1 → 4 0 0 1
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
target 을 찾았으면 즉시 break — 안 그러면 뒤이은 방향 탐색이 결과를 덮어씀.
for (int dir = 0; dir < 4; dir++) {
if (조건) {
// 처리
break; // ← 핵심
}
}
정리
- 90° 회전: 부분 영역 좌표 변환 식 외워두기.
- PBC: 0-base vs 1-base · 음수 처리 · big distance 도 Math.abs + N 더하기.
- Sort: Long 은 compareTo · 다중 조건 chain.
- Spiral: 방향 + ref_depth 패턴.
- List.remove:
i--잊지 말 것. - Loop 탐색: 찾으면 즉시 break.
- 조건 범위: 전역 vs 국부 — 문제 읽을 때 가장 신경 쓸 부분.
📦 이 글은 제가 운영하던 티스토리 블로그에서 옮겨온(migration) 글입니다. 원문: taehyuklee.tistory.com/17

댓글