마이의 개발 블로그

[프로그래머스] 기능개발 (Java) 본문

코딩테스트/프로그래머스

[프로그래머스] 기능개발 (Java)

개발자마이 2022. 3. 3. 21:25
반응형
 

코딩테스트 연습 - 기능개발

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다. 또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는

programmers.co.kr

 

작성 코드

  1. 배포완료된 횟수가 주어진 progresses의 길이와 같을 때까지 반복한다(while문).

  2. 한 번 반복 시 배포 완료된 작업을 제외하고, progresses에 speeds를 더한다.

  3. 더해진 progresses를 체크하여 완료작업을 배포하고(count++), 완료되었음을 표시해준다(-1).

  4. 한 회당 배포완료작업의 개수를 저장하고(list.add(count)), 전체 배포완료개수(countSum)에 더해준다.

 

//내가 작성한 코드
import java.util.*;

class Solution {
    public int[] solution(int[] progresses, int[] speeds) {
   
        int[] answer = {};
        
        int countSum = 0;
        int round = 0;
        
        List<Integer> list = new ArrayList<Integer>();
        
        while(countSum < progresses.length){
            
            //작업속도 더해주기
            for(int i=0; i<progresses.length; i++){
                
                if(progresses[i] != -1) //배포 완료된 작업이 아닐 경우
                    progresses[i] += speeds[i];
            }
            
            int count = 0;
            
            //완료작업유무 체크하기
            for(int i=0; i<progresses.length; i++){
                
                //이미 추가된 작업은 건너뛰기
                if(progresses[i] == -1)
                    continue;
    
                if(progresses[i] < 100)  //미완료 작업일 경우 반복중지
                    break;
                else{                   //완료된 작업 배포 및 표시 
                    count++;
                    progresses[i] = -1;
                } 
                
            }
            
            if(count > 0){
               list.add(count);    
            }
            
            countSum += count;
        }
        
        answer = new int[list.size()];
        
        for(int i=0; i<list.size(); i++){
            answer[i] = list.get(i);
        }
        
        return answer;
    }
}

무식하게 for문으로 풀었기 때문에 어려운 건 없었는데, 다른 사람들 풀이를 찾아보니 성능면에서 몇 가지 참고할만한 내용이 있어 비교해본다.

 

  - 작업 완료에 필요한 소요일수를 먼저 계산한다.

  - 계산된 소요일수를 Queue에 저장하고 사용한다.

 

//수정사항을 적용한 코드
import java.util.*;

class Solution {
    public int[] solution(int[] progresses, int[] speeds) {
   
        int[] answer = {};
        
        Queue<Integer> queue = new LinkedList<>();
        
        for(int i=0; i<progresses.length; i++){
            queue.add((int) Math.ceil((100.0 - progresses[i])/speeds[i]));
        }
        
        List<Integer> list = new ArrayList<>();
                      
        while(!queue.isEmpty()){
            
            int progress = queue.poll();
            int count = 1;
            
            while(!queue.isEmpty() && queue.peek() <= progress){
                queue.poll();
                count++;
            }
            
            list.add(count);
        }
        
        answer = new int[list.size()];
                      
        for(int i=0; i<list.size(); i++){
            answer[i] = list.get(i);
        }          
                      
        return answer;
    }
}

 

내 방식과 비교해봤을 때 이렇게 하면

 

  1) 매번 progresses에 speeds를 더하는 연산을 줄일 수 있고,

  2) 종료조건 체크를 위해 사용하던 countSum과 관련된 연산도 필요없어지는 것 같다.

 

고 생각해서 훨씬 효율적이겠거니 생각했는데... 막상 소요시간이 그렇게까지 크게 차이나진 않았다.

반응형
Comments