PS❯BOJ2022-01-313 min read
[BOJ 5430] AC - Java (덱 Deque 기반 R/D 연산 최적화)
매 뒤집기 연산(R) 시 실제 배열을 뒤집지 않고 방향 플래그와 양방향 Deque를 활용해 O(N)으로 해결하는 문제
#BOJ#자료구조#덱#Deque#파싱#Java
1. 문제 개요 및 조건 분석
| 항목 | 내용 |
|---|---|
| 문제 이름 | AC (백준 5430번 / 골드 5) |
| 플랫폼 / 난이도 | 백준 (골드 5, 5430번) |
| 문제 링크 | 백준 5430번 |
| 제한 사항 | 시간 제한 1초, 메모리 제한 256MB |
| 입력 조건 | 테스트 케이스 $T \le 100$, 수행할 함수 $P$ 길이 $\le 100,000$, 배열 크기 $N \le 100,000$, $\sum (P + N) \le 700,000$ |
| 핵심 명령어 | R(뒤집기: 순서 뒤집기), D(버리기: 첫 번째 수 버리기, 빈 배열일 때 에러) |
2. 접근 아이디어: R 연산 시뮬레이션의 함정과 Deque 최적화
⚠️ 왜 단순 뒤집기는 시간 초과인가?
- 길이 $N$인 배열에 대해
R이 들어올 때마다 실제로 원소들을 뒤집으면 $O(N)$이 소요됩니다. - 명령어 $P$에
R이 연속으로 여러 번 주어질 경우 최악 $O(P \times N) \approx 100,000 \times 100,000 = 10^{10}$으로 1초 시간 제한을 아득히 초과합니다.
💡 해결책: 방향 플래그와 양방향 덱(Deque)
- 방향 플래그 (
isReversed):R명령이 들어오면 실제로 원소를 조작하지 않고, 방향 상태(direction = -direction)만 $O(1)$에 뒤집습니다.
- 양방향 삭제 (
ArrayDeque):- 정방향일 때
D명령: 앞에서 제거 (pollFirst()) - 역방향일 때
D명령: 뒤에서 제거 (pollLast()) - 원소가 비어있는데
D를 수행해야 하면 즉시error플래그를 켜고 테스트 케이스를 종료합니다.
- 정방향일 때
- 최종 출력 포맷:
- 최종 방향 상태에 맞추어 앞 또는 뒤에서 꺼내며
[x1,x2,...,xn]형태로 문자열을 생성합니다.
- 최종 방향 상태에 맞추어 앞 또는 뒤에서 꺼내며
3. Java 풀이 코드
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int tc = Integer.parseInt(br.readLine());
while (tc-- > 0) {
String commands = br.readLine();
int n = Integer.parseInt(br.readLine());
String arrStr = br.readLine();
ArrayDeque<Integer> deque = parseArray(arrStr);
boolean isReversed = false;
boolean isError = false;
for (int i = 0; i < commands.length(); i++) {
char cmd = commands.charAt(i);
if (cmd == 'R') {
isReversed = !isReversed;
} else if (cmd == 'D') {
if (deque.isEmpty()) {
isError = true;
break;
}
if (isReversed) {
deque.pollLast();
} else {
deque.pollFirst();
}
}
}
if (isError) {
sb.append("error\n");
} else {
sb.append(formatDeque(deque, isReversed)).append("\n");
}
}
System.out.print(sb);
}
// 대괄호와 쉼표를 파싱하여 Deque에 삽입
private static ArrayDeque<Integer> parseArray(String s) {
ArrayDeque<Integer> deque = new ArrayDeque<>();
s = s.substring(1, s.length() - 1); // '['와 ']' 제거
if (s.isEmpty()) return deque;
String[] tokens = s.split(",");
for (String token : tokens) {
deque.addLast(Integer.parseInt(token.trim()));
}
return deque;
}
// 방향에 맞게 출력 문자열 생성
private static String formatDeque(ArrayDeque<Integer> deque, boolean isReversed) {
StringBuilder sb = new StringBuilder();
sb.append("[");
while (!deque.isEmpty()) {
sb.append(isReversed ? deque.pollLast() : deque.pollFirst());
if (!deque.isEmpty()) {
sb.append(",");
}
}
sb.append("]");
return sb.toString();
}
}
4. 복잡도 분석
- 시간 복잡도: $O(P + N)$ — 각 명령은 $O(1)$에 수행되며, 파싱 및 출력 역시 각 원소당 $O(1)$에 완료됩니다. 전체 테스트케이스 합 $\sum(P+N) \le 700,000$이므로 약 0.3초 내에 여유 있게 통과.
- 공간 복잡도: $O(N)$ — 덱에 최대 $10만$ 개의 정수를 저장하므로 256MB 제한 내에서 매우 안정적.
5. 채점 결과 및 통과 인증

← PREVIOUS LOG
[프로그래머스] 더 맵게 - Java (우선순위 큐 PriorityQueue / 힙 Heap)
NEXT LOG →[프로그래머스] 신고 결과 받기 - Java (2022 KAKAO BLIND RECRUITMENT)
COMMENTS // GITHUB DISCUSSIONS (GISCUS)