[프로그래머스] - LV2. 더 맵게(JAVA)

개발자·2022년 9월 26일
0
post-thumbnail

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

문제 접근

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

약간의 고찰(for vs stream)

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

  • for문을 순회하면서 검사
  • 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

대충 요약하자면, 일반적인 로직에서는 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();
    }
}
profile
I DEVELOP THEREFORE, I AM 😄

0개의 댓글