공부/알고리즘, 자료구조

[프로그래머스] 프린터

오잎 클로버 2022. 2. 15. 08:30
728x90

 해당 문제의 링크는 여기입니다. 

다른 분들이 푸신 방법이 더 좋을 수도 있지만

제가 생각해낸 방법으로 포스팅하도록 하겠습니다.

(대부분 Inner Class, Queue 둘 중 하나, 혹은 둘 다 사용하셔서 푸셨습니다.

저 같은 경우에는 Queue만 사용하여 해결했습니다.)

 

제한사항

  1. 인쇄 대기목록의 가장 앞에 있는 문서(J)를 대기목록에서 꺼냄
  2. 나머지 인쇄 대기목록에서 J보다 중요도가 높은 문서가 한 개라도 존재하면 J를 대기목록의 가장 마지막에 넣음
  3. 그렇지 않으면 J를 인쇄

알고리즘

문제를 파악함에 있어 제가 가장 중요하게 확인한 점은

값이 같더라도 위치를 정확하게 파악하는 것이었습니다.

그리고 해당 값을 인쇄, 즉 사라지게 된 후에는 다시 제한사항을 반복한다는 점이었습니다.

 

그래서 개인적으로 현재 값이 모든 문서들 중 가장 큰 수인지 파악을 해야한다고 생각하여

메소드를 만들었습니다.

public boolean isHighest(int current, Queue<Integer> papers) {
    for (int i : papers) {
        if (i > current) {
            return false;
        }
    }
    return true;
}

그리고 현재 위치를 계속하여 저장하기 위해

tempLocation이라는 변수를 만들고

내 문서를 인쇄하기까지 총 몇 개의 문서들을 인쇄하였는 지 저장하기 위해 result 변수를 만들었습니다.

int tempLocation = location;
int result = 0;

while를 사용하여 

모든 문서들을 전부 인쇄하기까지 계속 반복하도록 하고

제일 첫 번째에 위치한 현재 문서(J)를 peek로 임시로 저장하였습니다.

int current = papers.peek(); // 제일 처음 값

그리곤 현재 제일 처음에 위치한 값이 제일 큰 값인지 파악합니다.

if (isHighest(current, papers)) {
    // 현재 값이 제일 크다면
}
else {
    // 아니라면
}

제일 크든 아니든 둘 다 remove를 사용하여 없앴습니다.

 

if (isHighest(current, papers)) {
    // 현재 값이 제일 크다면
    if (tempLocation < 0) {
        continue;
    }

    if (tempLocation == 0) {
        tempLocation = -1;
    }
    result++;
    tempLocation--;
}

현재 값이 제일 크다면

내 문서 위치가 정상적인지 파악합니다.

만일 내 문서 위치가 제일 첫 번째, 즉 현재 값이라면

문서 위치를 비정상적으로 만들고

나머지 로직인 result를 +1하고 내 문서 위치를 -1 합니다.

(내 문서 위치를 1 줄이는 이유는 점점 0에 가까이 하도록 만들기 위함입니다.

 

else {
    // 현재 값이 제일 크지 않다면
    papers.add(current);
    if (tempLocation == 0) {
        tempLocation = papers.size() - 1;
    }
    else {
        tempLocation--;
    }
}

현재 값을 맨 뒤로 이동시키라는 조건이 있었기에

말그대로 다시 뒤로 추가합니다.

현재 값이 제일 크지 않지만, 내 문서가 제일 첫 번째에 있다면

해당 위치를 기억하고자 (모든 문서 길이 - 1 = 실제 최대 인덱스)로 저장합니다.

내 문서가 아니라면 내 문서 위치를 -1합니다.

 

return result;

내 문서가 인쇄되기까지 총 몇번의 인쇄를 하였는 지 result에 저장되어있기에

result만 반환해주면 끝납니다.

 

전체 소스코드

import java.util.*;

class Solution {
    public int solution(int[] priorities, int location) {
        Queue<Integer> papers = new ArrayDeque<>();
        for (int paper : priorities) {
            papers.add(paper);
        }

        int tempLocation = location;
        int result = 0;
        while (!papers.isEmpty()) {
            // 중복값이 있더라도 내 위치를 정확하게 알아내야함

            int current = papers.peek(); // 제일 처음 값
            if (isHighest(current, papers)) {
                // 현재 값이 제일 크다면
                papers.remove();

                if (tempLocation < 0) {
                    continue;
                }

                if (tempLocation == 0) {
                    tempLocation = -1;
                }
                result++;
                tempLocation--;
            }
            else {
                // 현재 값이 제일 크지 않다면
                papers.remove();
                papers.add(current);
                if (tempLocation == 0) {
                    tempLocation = papers.size() - 1;
                }
                else {
                    tempLocation--;
                }
            }
        }

        return result;
    }

    public boolean isHighest(int current, Queue<Integer> papers) {
        for (int i : papers) {
            if (i > current) {
                return false;
            }
        }
        return true;
    }

}

 

추가로...

만일 제 코드가 아닌 본인만의 방식으로 해결 중인데

테스트케이스는 문제없지만 제출 시, 나오는 테스트케이스에서 문제가 발생하실 수 있기에

테스트케이스 하나 드리고자합니다.

[0, 9, 3, 8, 2, 0, 7] 를 priorities로 location은 0 혹은 6으로 두고 테스트 케이스 만들어 테스트 해보세요.

location 0일때에는 7이 결과로 나오고, 6일때는 3으로 나옵니다.

 

 

이상입니다.