[프로그래머스] [java] 기능개발

파워소동·2023년 9월 14일
0

프로그래머스

목록 보기
1/3

이 문제는 스택/큐 문제다.
근데 전에 이 문제를 풀었을때 스택/큐 안 쓰고 걍 풀었었다...ㅋㅋㅋ(맨땅에 헤딩 전문임)

큐를 이용해서 다시 풀어봤당.

queue로 풀기

import java.util.*;

class Solution {
    Queue<Integer> progressQueue = null; // 남은 기능 진도 큐
    Queue<Integer> speedsQueue = null; // 기능 작업속도 큐
    
    public int[] solution(int[] progresses, int[] speeds) {
        progressQueue = new LinkedList<>(Arrays.asList(Arrays.stream(progresses).boxed().toArray(Integer[]::new)));
        speedsQueue = new LinkedList<>(Arrays.asList(Arrays.stream(speeds).boxed().toArray(Integer[]::new)));

        List<Integer> result = new ArrayList<>();
        int day = 1;	// 1일차, 2일차 ...
        while(!progressQueue.isEmpty()) {
            int dayCount = dayPop(day, 0);
            // 그 날 배포할 수 있는 기능이 0개면 결과list에 넣지 않는다.
            if(dayCount!=0) {
                result.add(Integer.valueOf(dayCount));
            }
            day++;
        }
        
        // 결과 list를 array로 바꾸어서 return
        return result.stream()
                .mapToInt(Integer::intValue)
                .toArray();
    }
    
    public int dayPop(int day, int sumCount) {
        // 남은 기능이 없으면 return
        if(progressQueue.isEmpty()) {
            return sumCount;
        }
        
        // 지난 날짜 * 작업속도 + 진도값이 100이 넘으면 queue의 첫번째 값을 poll하고 두번째 값도 배포가 가능한지 재귀
        int value = day*speedsQueue.peek()+progressQueue.peek();
        if(value >= 100) {
            speedsQueue.poll();
            progressQueue.poll();
            return this.dayPop(day, ++sumCount);
        } else {
            return sumCount;
        }
    }
}


근데 속도 효율이 똥임 ... ㅠㅠㅠ

재귀함수 제거

재귀함수를 써서 그런가?!?!?
반복문으로 바꾸어 봤다.

import java.util.*;

class Solution {
    Queue<Integer> progressQueue = null; // 남은 기능 진도 큐
    Queue<Integer> speedsQueue = null; // 기능 작업속도 큐
    
    public int[] solution(int[] progresses, int[] speeds) {
        progressQueue = new LinkedList<>(Arrays.asList(Arrays.stream(progresses).boxed().toArray(Integer[]::new)));
        speedsQueue = new LinkedList<>(Arrays.asList(Arrays.stream(speeds).boxed().toArray(Integer[]::new)));

        List<Integer> result = new ArrayList<>();
        int day = 1;	// 1일차, 2일차 ...
        while(!progressQueue.isEmpty()) {
            int dayCount = 0;
            int value = day*speedsQueue.peek()+progressQueue.peek();
            while(value >= 100) {
                dayCount++;
                speedsQueue.poll();
                progressQueue.poll();
                
                if(speedsQueue.isEmpty()) {
                    value = 0;
                    continue;
                }
                value = day*speedsQueue.peek()+progressQueue.peek();
            }
            
            // 그 날 배포할 수 있는 기능이 0개면 결과list에 넣지 않는다.
            if(dayCount!=0) {
                result.add(Integer.valueOf(dayCount));
            }
            day++;
        }
        
        // 결과 list를 array로 바꾸어서 return
        return result.stream()
                .mapToInt(Integer::intValue)
                .toArray();
    }
}


조금은 빨라진듯하나 효과는 미미했다..

stream 제거

예전에 stream의 속도가 느리다는 글을 읽은적이 있는데 혹시나해서 stream을 for로 수정해봤다.

import java.util.*;

class Solution {
    Queue<Integer> progressQueue = new LinkedList<>(); // 남은 기능 진도 큐
    Queue<Integer> speedsQueue = new LinkedList<>(); // 기능 작업속도 큐
    
    public int[] solution(int[] progresses, int[] speeds) {
        for(int i = 0 ; i < progresses.length ; i++) {
            progressQueue.offer(progresses[i]);
            speedsQueue.offer(speeds[i]);
        }
        

        List<Integer> result = new ArrayList<>();
        int day = 1;	// 1일차, 2일차 ...
        while(!progressQueue.isEmpty()) {
            int dayCount = 0;
            int value = day*speedsQueue.peek()+progressQueue.peek();
            while(value >= 100) {
                dayCount++;
                speedsQueue.poll();
                progressQueue.poll();
                
                if(speedsQueue.isEmpty()) {
                    value = 0;
                    continue;
                }
                value = day*speedsQueue.peek()+progressQueue.peek();
            }
            
            // 그 날 배포할 수 있는 기능이 0개면 결과list에 넣지 않는다.
            if(dayCount!=0) {
                result.add(Integer.valueOf(dayCount));
            }
            day++;
        }
        
        // 결과 list를 array로 바꾸어서 return
        int[] resultArray = new int[result.size()];
        for(int i = 0; i < result.size(); i++){
            resultArray[i] = result.get(i);
        }
        return resultArray;
    }
}

오!!!!!

코드의 가독성은 조금 떨어지지만 확실히 속도가 줄어들었다

속도가 중요할 때는 for을, 유지보수가 잘 되도록 클린한 코드를 짤 때에는 stream을 선택해서 쓰면 좋을 것 같다.

그럼~~
끝!

0개의 댓글