[프로그래머스/Level2] 더 맵게(Java)

SeokHyun·2022년 6월 30일
0

프로그래머스

목록 보기
8/32

문제 링크: https://programmers.co.kr/learn/courses/30/lessons/42626

문제 접근

  1. 배열을 우선순위 큐로 바꿈
  2. 우선순위 큐에서 2개를 꺼내서 섞고 다시 넣음
  3. 우선순위 큐에 존재하는 음식이 다 K를 넘는지 확인
  4. 넘으면 횟수 리턴
  5. 아니면 1번부터 다시 진행
    5-1. 여기서 우선순위 큐의 크기가 1이면 -1 리턴

약간의 고찰(for vs stream)

우선순의 큐에 모든 음식이 K를 넘는지 확인하는 방법을 두가지로 구현해봤다.

  1. for문을 순회하면서 검사
  2. stream을 이용하여 검사

위의 두가지 방법으로 효율성 테스트를 비교해보겠다.

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

대충 요약하자면, 일반적인 로직에서는 streamfor문보다 느린데 로직이 복잡해지면 for문과 성능 차이가 그다지 크지 않다.

오히려, 병렬처리 streamparallelStream을 사용하여 복잡한 로직을 처리하면 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();
    }
}
profile
SI를 넘어 백엔드 엔지니어를 향하여

0개의 댓글