ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 프린터
    프로그래머스/스택, 큐 2022. 2. 4. 22:01

     

    <최종 코드>

    import java.util.*;
    
    class Solution {
        public int solution(int[] priorities, int location) {
            
            int N = priorities.length;
            
            List<Integer> importance = new ArrayList<>();  
            
                for(int i = 0; i<N; i++) {
                    importance.add(priorities[i]);
                }
            
            Queue<Integer> papers = new LinkedList<>();
            
                for(int i=0; i<N; i++) {
                    papers.add(i);
                }
            
            int count = 1;
            
                 while(!papers.isEmpty()) {
    	        	int number=0;
    	        	int size = importance.size();
    	        	int max = -1;
    	        	
    	            for(int i=0; i<size; i++) {
    	            	
    	                max = Math.max(max,importance.get(i));	
    	             }	
    	            	
    	          
    	            for(int i=0; i<size; i++) {
    	                	
    	                    if(importance.get(i) < max) {          	
    	                        number++;
    	                        
    	                    }else {
    	                    	break;
    	                    }
    	                }
    	                  
    	                if(number != 0) {
    	                
    	                   while(number -- > 0){
    	                    int M = importance.get(0);
    	                  
                            importance.remove(0);
                            importance.add(M);
                       
                            int K = papers.poll();
                            papers.add(K);
                        
    	                }
    	              }
    	                
    	                        if(papers.peek() == location) {
    	                            break;
                                    
    	                        }else {
    	                            importance.remove(0);
    	                        	papers.remove();
    	                            count++;
                                   }
    	                       }
                     return count;
                  }
                }

    되게 복잡해 보인다.

    다음에는 더 간단하게 코드를 완성할 수 있는 능력이 생겼으면!!

     

    일단 예시에 나와있는,

    priorities = [2,1,3,2]

    location = 2

     

    이 부분을 가지고 설명하겠다.

     

    1. 초기화 

     

     

    위의 예시는, 중요도가 4개 나와 있으므로,

    총 준비된 문서가 4개라는 뜻이다.

    그래서 papers라는 큐를 만들어서, 여기에 4개의 문서, 즉 0 1 2 3 을 집어넣었다.

    0은 첫번째 문서이다

     

    나는 이때, 배열 priorities 값을 importance 라는 리스트에 옮겨 담았다.

    그 이유는 리스트 크기를 동적으로 변경시킬 수 있기 때문이다.

     

    이때 importance와 papers는 움직임이 같아야 한다.

     

    예시의 

    priorities = [2,1,3,2] 에서 설명하자면,

    중요도는 3이 제일 크다.

    그렇다 함은, 세번째 문서가 제일 먼저 출력된다는 뜻이다.

     

    그래서, 앞의 2 1 문서는 뒤로 밀리고 세번째 문서가 제일 먼저 출력된다.

     

    importance : 2 1 3 2 -> 1 3 2 2 -> 3 2 2 1 -> 3 삭제됨.

    이때,

    papers 도 같은 움직임을 보인다.

    0 1 2 3 -> 1 2 3 0 -> 2 3 0 1 -> 2삭제

     

    더보기

    그런데 여기서 importance 는 리스트로, papers는 스택으로 사용하는 이유는,

     

    importance 에서 제일 큰 값 3을 찾을 때, 인덱스를 활용해서 2 1 3 2 값들을 서로 비교할 것인데,

     

    이때 스택에는 인덱스를 활용할 방법이 없다.

     

    그래서 리스트를 사용해서 비교하도록 했다.

     

    그래서 위의 코드에서 아래와 같이 importance 와 papers 초기화를 진행했다.

     

            int N = priorities.length;
            
            List<Integer> importance = new ArrayList<>();  
            
                for(int i = 0; i<N; i++) {
                    importance.add(priorities[i]);
                }
            
            Queue<Integer> papers = new LinkedList<>();
            
                for(int i=0; i<N; i++) {
                    papers.add(i);
                }

     

     

    2. 제일 큰 중요도 찾기(max 변수)

     

       		for(int i=0; i<size; i++) {
    	            	
    	                max = Math.max(max,importance.get(i));	
    	             }

     

    이 코드에서 중요도 2 1 3 2 중 가장 큰 값인 3을 max로 지정했다.

     

     

     

    3. number 변수

     

    2 1 3 2 예에서 보면,

    max 값인 3보다 작은 2 1 이 앞에 있다.

    즉 2개가 있다.

    이 경우 number 라는 변수에 2가 입력되도록 한다.

       
    	            for(int i=0; i<size; i++) {
    	                	
    	                    if(importance.get(i) < max) {          	
    	                        number++;
    	                        
    	                    }else {
    	                    	break;
    	                    }
    	                }

     

    4. importance, papers 변경

     

    위에서 number 값을 2로 했다.

    importance, papers에서 값을 꺼내서 다시 넣어주는 것을 2회 진행한다.

     

    importance : 2 1 3 2 -> 1 3 2 2 -> 3 2 2 1 

    papers : 0 1 2 3 -> 1 2 3 0 -> 2 3 0 1

     

     

     

             if(number != 0) {
    	                
    	                   while(number -- > 0){
    	                    int M = importance.get(0);
    	                  
                                importance.remove(0);
                                importance.add(M);
                       
                                int K = papers.poll();
                                papers.add(K);
                        
    	                }
    	              }

     

     

     

     

    5. count 세기

                            if(papers.peek() == location) {
    	                            break;
                                    
    	                        }else {
    	                            importance.remove(0);
    	                        	papers.remove();
    	                            count++;
                                   }

    위의 4번 코드로 아래와 같은 상태가 됐다.

    importance : 2 1 3 2 -> 1 3 2 2 -> 3 2 2 1

    papers : 0 1 2 3 -> 1 2 3 0 -> 2 3 0 1

     

    이때, papers의 맨 앞에 있는 값은 2 이다.

     

    그리고 문제에서 location 으로 준 값도 2이다.

    (즉, 세번째 문서가 언제 인쇄될지 리턴)

     

    그러면 papers.peek() == location 을 만족하기 때문에,

    break 로 while 문이 종료 되고 

    count 가 리턴된다.

     

    count 값은 처음에 1로 초기화 되었기 때문에,

    결국 1이 리턴된다.

    즉, 우리가 찾고자 했던 세번째 문서는 맨 처음 출력되기 때문에 1이 리턴되는 것이다.

     

    ---

     

    하지만 이 예시 말고 두 번째 예시는

    importance : 1 1 9 1 1 1 

    location : 0

    이다.

     

    이 경우는, 

    importance : 1 1 9 1 1 1 -> 1 9 1 1 1 1 -> 9 1 1 1 1 1 

    papers : 0 1 2 3 4 5 -> 1 2 3 4 5 0 -> 2 3 4 5 0 1

     

    이렇게 되는데, papers.peek() = 2, location = 0 이기 때문에

    papers.peek() 와 location 값이 다르다.

     

    그래서 importance 와 papers 에서 맨 앞 값을 삭제한 뒤,

    importance : 1 1 1 1 1 

    papers : 3 4 5 0 1

     

    count 값을 올려주고, 다시 while 문을 돈다.

     

    계속 돌다가, papers.peek() 와 location 이 같을 때 멈춘뒤 count 값을 리턴한다.

     

    그리고 끝난다.

     

    ----------------

    # 유의점

     

    이 문제를 풀면서 제일 유의해야 했던 점은, 아래 코드이다.

                     while(number -- > 0){
    	                    int M = importance.get(0);
    	                  
                            importance.remove(0);
                            importance.add(M);
                       
                            int K = papers.poll();
                            papers.add(K);
                        
    	                }

    나는 처음에 while 문이 아니라 for문을 사용해서,

    for(int i=0; i<number ; i++) 

    이런 식으로 importance와 papers 에서 맨 앞에 있는 값을 제거하고, 다시 넣어주도록 했다.

     

    그런데 문제가 있었다.

     

    예를들어 위의 예시 

    importance : 2 1 3 2 를 보자.

     

    i=0 일때

    importance.remove(0) 으로

    제일 먼저 2를 빼낸다.

    그리고 다시 넣는다.

    그러면 1 3 2 2 가 된다.

     

    그리고 나면 i=1 이 된다.

    그런데 보자.

    우리는 지금 1을 빼서 다시 넣어줘야 하는데,

    i=1 은 1이 아니라 3이다.

    (즉 리스트는 맨 앞의 값을 빼내면 뒤의 값이 앞으로 채워진다.)

     

    그래서 importance.remove(1) 을 하면 1을 빼내는 게 아니라, 3이 빼져서, 오류가 생기게 된다.

     

    따라서 이런 부분은 유의를 해줘야 한다!!

     

     

     

    댓글

Designed by Tistory.