프로그래머스 같은 숫자는 싫어 풀이 과정
스택으로 먼저 풀고, 덱으로 리팩토링하다가 한 번 더 틀렸다.
마지막엔 스택/덱 없이 인덱스 비교만으로 가장 간결하게 정리했다.
총 4번의 제출
1트 (정답, 스택 활용)
→ 스택의 peek()으로 직전 값을 확인하고, 현재 값과 같으면 건너뛴다.
→ 스택과 별도로 List에도 같이 담아서 최종 배열을 구성했다.
import java.util.*;
public class Solution {
public int[] solution(int []arr) {
Stack<Integer> stack = new Stack<>();
List<Integer> list = new ArrayList<>();
stack.push(arr[0]);
list.add(arr[0]);
for(int i=1; i<arr.length; i++) {
if(stack.peek()==arr[i]) continue;
else {
stack.push(arr[i]);
list.add(arr[i]);
}
}
int[] answer = new int[list.size()];
for(int i=0; i<list.size(); i++) {
answer[i] = list.get(i);
}
return answer;
}
}
위 풀이의 결과
- 정답은 맞지만, 스택과 리스트를 동시에 관리하는 구조가 불필요하게 중복이다.
Stack만으로도 되는데 굳이List를 따로 유지한 셈이다.- 리팩토링 여지가 있어서 덱으로 다시 시도했다.
2트 (오답, 덱 활용)
→ Stack + List 조합 대신, 덱 하나로 처리하도록 변경했다.
→ peekLast()로 직전 값을 확인하고, 다르면 offer()로 뒤에 추가하는 방식.
import java.util.*;
public class Solution {
public int[] solution(int []arr) {
Deque<Integer> dq = new LinkedList<>();
for(int i : arr) {
if(dq.isEmpty()) {
dq.offer(i);
continue;
}
if(dq.peekLast() == i) continue;
else dq.offer(i);
}
int[] answer = new int[dq.size()];
for(int i=0; i<dq.size(); i++) {
answer[i] = dq.poll();
}
return answer;
}
}
위 풀이의 결과
dq.size()를 반복문 조건식에 직접 쓰면,dq.poll()로 요소를 꺼낼 때마다size()가 줄어들어 반복이 절반만 돌고 끝나버린다.- 결과적으로 배열 뒷부분이 전부 0으로 채워지는 오답이 발생한다.
3트 (정답, 덱 활용)
→ 반복문 진입 전에 dq.size()를 size 변수에 미리 저장해두고 고정값으로 사용했다.
import java.util.*;
public class Solution {
public int[] solution(int []arr) {
Deque<Integer> dq = new LinkedList<>();
for(int i : arr) {
if(dq.isEmpty()) {
dq.offer(i);
continue;
}
if(dq.peekLast() == i) continue;
else dq.offer(i);
}
int[] answer = new int[dq.size()];
int size = dq.size();
for(int i=0; i<size; i++) {
answer[i] = dq.pollFirst();
}
return answer;
}
}
위 풀이의 결과
size를 미리 고정해두니poll()로 꺼내도 반복 횟수가 줄어들지 않아 정상 동작한다.- 덱 하나로 깔끔하게 처리 완
4트 (리팩토링, 스택/덱 없이)
→ 스택도, 덱도 필요 없다는 걸 깨달았다.
→ arr[i] != arr[i-1] 인덱스 비교만으로 직전 값을 확인할 수 있으니, 그냥 List에 바로 담으면 된다.
import java.util.*;
public class Solution {
public int[] solution(int[] arr) {
List<Integer> list = new ArrayList<>();
list.add(arr[0]);
for(int i=1; i<arr.length; i++) {
if(arr[i] != arr[i-1]) list.add(arr[i]);
}
int[] answer = new int[list.size()];
for(int i=0; i<list.size(); i++) answer[i] = list.get(i);
return answer;
}
}
위 풀이의 결과
- 스택/덱의
peek()없이도 배열 인덱스로 직전 값 비교가 가능하다는 걸 활용했다. - 자료구조 오버헤드가 사라지고 코드가 훨씬 간결해졌다.
isEmpty()체크도 필요 없고,size저장 실수도 생길 여지가 없다.

리팩토링하다가 오히려 한 번 더 틀렸다.
dq.size()를 반복 조건에 그대로 쓰면 루프 도중에 값이 바뀐다는 게 맹점이었다. 앞으로 컬렉션을 순회하면서 동시에 꺼내는 경우엔 size를 미리 저장하는 습관을 들여야겠다.
그리고 이번 문제처럼 "직전 값과 비교"가 목적이라면 굳이 자료구조를 쓸 필요 없이 인덱스로 해결할 수 있다는 것도 기억해두자.
'CS > 코딩테스트' 카테고리의 다른 글
| 프로그래머스 - 프로세스 (JAVA) (0) | 2026.04.24 |
|---|---|
| 프로그래머스 - 올바른 괄호 (JAVA) (0) | 2026.04.24 |
| 프로그래머스 - 기능개발 (JAVA) (0) | 2026.04.24 |
| 프로그래머스 - 베스트 앨범 (JAVA) (0) | 2026.04.23 |
| 프로그래머스 - 전화번호 목록 (JAVA) (0) | 2026.04.23 |
