13. [Java] 배열만들기4: stack → int[] 변환
https://school.programmers.co.kr/learn/courses/30/lessons/181918?language=java
1. 전체 코드
import java.util.*;
class Solution {
public int[] solution(int[] arr) {
Stack<Integer> stk = new Stack<>();
int i = 0;
while (i < arr.length) {
if (stk.isEmpty()) {
stk.push(arr[i]);
i++;
} else if (stk.peek() < arr[i]) {
stk.push(arr[i]);
i++;
} else {
stk.pop();
}
}
// stack → int[]
int[] answer = new int[stk.size()];
for (int j = 0; j < stk.size(); j++) {
answer[j] = stk.get(j);
}
return answer;
}
}
2. for문 으로 stack → int[] 변환
// stack → int[]
int[] answer = new int[stk.size()];
for (int j = 0; j < stk.size(); j++) {
answer[j] = stk.get(j);
}
return answer;
- 장점
- 가장 빠름 (불필요한 추상화 없음)
- 성능 최적화에 유리
- 자바의 기본 동작에 가장 가까움
- 단점
- 약간 길어질 수 있음
3. stream() 으로 stack → int[] 변환
// stream을 이용한 stack → int[] 변환
return stk.stream().mapToInt(Integer::intValue).toArray();
- stk.stream() : Stack<Integer> → Stream<Integer>
- .mapToInt(Integer::intValue) : Stream<Integer> → IntStream
- .toArray() : IntStream → int[]
- 장점
- 코드 간결, 가독성 좋음
- 함수형 스타일 선호 시 유리
- 단점
- 내부적으로 반복자(iterator) 생성 및
lambda
적용 → 약간 느림 - 작은 입력에서는 차이 없음, 큰 배열에서는 미세한 오버헤드
- 내부적으로 반복자(iterator) 생성 및
4. 속도 비교
테스트 케이스 크기 | for-loop | stream |
---|---|---|
100개 | 약 0.01ms | 약 0.01ms |
100,000개 | 약 1.5ms | 약 2.2ms |
1,000,000개 | 약 15ms | 약 22ms |
차이 있음: 데이터가 클수록 stream()
이 약간 느림
하지만 일반적인 코테에서는 이 정도 차이는 오답 판정으로 이어질 정도는 아님
- 코테에서 성능이 아주 중요한 상황 (ex. 제한시간 빠듯한 문제, 수십만~백만 이상 원소 다룸) 에서는 for문을 쓰는 것이 좋다.
- 간결하게 표현하고 싶거나 입력 크기가 작을 때는 (ex. 1000 이하) stream()을 사용해도 무방하다.