티스토리 뷰

https://programmers.co.kr/learn/courses/30/lessons/42587

 

코딩테스트 연습 - 프린터 | 프로그래머스

일반적인 프린터는 인쇄 요청이 들어온 순서대로 인쇄합니다. 그렇기 때문에 중요한 문서가 나중에 인쇄될 수 있습니다. 이런 문제를 보완하기 위해 중요도가 높은 문서를 먼저 인쇄하는 프린터를 개발했습니다. 이 새롭게 개발한 프린터는 아래와 같은 방식으로 인쇄 작업을 수행합니다. 1. 인쇄 대기목록의 가장 앞에 있는 문서(J)를 대기목록에서 꺼냅니다. 2. 나머지 인쇄 대기목록에서 J보다 중요도가 높은 문서가 한 개라도 존재하면 J를 대기목록의 가장 마지막에

programmers.co.kr

import java.util.Arrays;

public class StackQueueExam01 {
	public static void main(String[] args) {
//		int[] priorities = {2, 1, 3, 2};
//		int location = 2;	
//		which returns 1
		
		int[] priorities = {1, 1, 9, 1, 1, 1};
		int location = 0;	
//		which returns 5
		
		System.out.println(solution(priorities, location));
	}
	
	static int solution(int[] priorities, int location) {
        int answer = 0;
        
        while(priorities.length != 0) {
        	int first = priorities[0];	// 인쇄 대기목록에서 가장 앞에 있는 문서
        	boolean firstPriority = true;	// 목록 중 중요도가 가장 높은지 여부
        	
            	// 목록에 중요도가 더 높은 문서가 있는지 확인한다
        	for (int i = 1; i < priorities.length; i++) {
        		if(first < priorities[i]) {	
				// 문서를 대기목록의 가장 마지막으로 보낸다
        			int[] newArray = new int[priorities.length];
        			for (int j = 1; j < priorities.length; j++) {
					newArray[j-1] = priorities[j];
				}
    	        		newArray[priorities.length-1] = first;
    	        		priorities = newArray;
				// 내가 인쇄를 요청한 문서의 위치
				if(location < 1) 
                			location = priorities.length;
				location--;
				// 대기목록의 순서가 바뀜으로써 변화 발생
				firstPriority = false;
				break;
			}
		}
        	
            	// 가장 높은 중요도의 문서인 경우, 인쇄한다
        	if(firstPriority) { 
        		answer++;			// 인쇄 순서
        		if(location == 0) break;	// 내가 인쇄를 요청한 문서인 경우
        		// 내가 요청한 문서가 아닌 경우, 변화된 문서의 위치와 대기목록을 갱신한다  
        		priorities = Arrays.copyOfRange(priorities, 1, priorities.length);	
        		location--;					
        	}
            
        }
        return answer;
    }
}

 배열을 이용해서 풀었는데 대부분 큐를 많이 이용한 것 같고, 구현이 깔끔해 보였다. 큐 문제이기 때문에 처음에 큐를 떠올렸는데 큐에 있는 요소의 값을 비교하는 방법이 생각이 나지 않더라. 간단한 것을.. 다른 사람의 코드를 보니 Collections 클래스의 max() 메서드를 사용해 이 값과 맨 앞의 값을 비교했다. 추가로, 중요도가 낮아 마지막으로 보내는 경우, 역시 Collections 클래스의 rotate() 메서드를 써서 손쉽게 순서를 변경할 수 있을 것 같다.

 배열의 첫 번째 요소를 맨 뒤로 보낼 때, 첫 번째 요소의 값을 저장해 두었다가 이후의 요소를 Arrays 클래스의 copyOfRange()를 써서 배열의 앞으로 복사하고 배열의 마지막에 이 값을 넣는 개념으로 접근했다가 잘못된 점을 찾았다. 복사한 배열의 크기만 한 배열을 생성해 반환하는 것이 당연한데 기존의 배열에 덮어쓰는 방식을 떠올리고 혼동했다. 새 배열을 생성하고 참조 변수를 바꿀 필요 없이 해당 부분을 아래와 같이 변경한다.

// 문서를 대기목록의 가장 마지막으로 보낸다
for (int j = 1; j < priorities.length; j++) {
	priorities[j-1] = priorities[j];
}
priorities[priorities.length-1] = first;

 큐를 사용해서 다시 풀어봐야겠다.  

댓글