문제 링크: https://programmers.co.kr/learn/courses/30/lessons/42626
우선순의 큐에 모든 음식이 K를 넘는지 확인하는 방법을 두가지로 구현해봤다.
for문을 순회하면서 검사
아마 이 방법을 제일 많이 쓸 것이다.
public boolean isAllSpicy(PriorityQueue<Integer> pq, int K) {
for (int num : pq) {
if (num < K) {
return false;
}
}
return true;
}
검사 코드는 위와 같으며, 효율성 테스트 검사 결과는 아래와 같다.
stream을 이용하여 검사
stream은 java8버전부터 도입이 되었다.
개인적으로 for문보다 가독성이 좋아 현재 프로젝트에서도 많이 사용을 하고 있다.
public boolean isAllSpicy(PriorityQueue<Integer> pq, int K) {
return !pq.stream()
.filter(num -> num < K)
.findFirst()
.isPresent();
}
검사 코드는 위와 같으며, 효율성 테스트 검사 결과는 아래와 같다.
고찰
for문을 이용하여 검사한 방법이 stream을 이용한 방법보다 더 빠르고 적은 메모리를 사용하는 것을 확인할 수 있다.
이는 stream이 비용이 크기 때문인데, 자세한 내용은 아래 링크를 참고하자.
링크: https://jypthemiracle.medium.com/java-stream-api%EB%8A%94-%EC%99%9C-for-loop%EB%B3%B4%EB%8B%A4-%EB%8A%90%EB%A6%B4%EA%B9%8C-50dec4b9974b
대충 요약하자면, 일반적인 로직에서는 stream이 for문보다 느린데 로직이 복잡해지면 for문과 성능 차이가 그다지 크지 않다.
오히려, 병렬처리 stream인 parallelStream을 사용하여 복잡한 로직을 처리하면 for문보다 더 좋은 성능을 보여준다.
import java.util.*;
class Solution {
public int solution(int[] scoville, int K) {
int count = 0;
PriorityQueue<Integer> pq = new PriorityQueue<>();
for (int num : scoville) {
pq.add(num);
}
int mixed = 0;
int firstScoville = 0;
int secondScoville = 0;
while(pq.size() > 1) {
count++;
//가장 맵지 않은 음식과 두번째로 맵지 않음 음식을 꺼냄
firstScoville = pq.poll();
secondScoville = pq.poll();
mixed = firstScoville + (secondScoville * 2);
pq.add(mixed);
if (isAllSpicy(pq, K)) {
return count;
}
}
return -1;
}
public boolean isAllSpicy(PriorityQueue<Integer> pq, int K) {
for (int num : pq) {
if (num < K) {
return false;
}
}
return true;
// return !pq.stream()
// .filter(num -> num < K)
// .findFirst()
// .isPresent();
}
}