Queue는 선형 메모리 공간에 데이터를 저장하는 선입선출(FIFO)방식의 자료구조이다.
Queue 자체로는 인터페이스이기 때문에 인스턴스 생성이 불가능하다.
Queue 인터페이스를 상속받는 하위 인터페이스들은 Deque, BlockingQueue, BlockingDeque, TransferQueue 등등 다양하지만 대부분 큐는 LinkedList를 이용한다.
LinkedList는 List도 상속받았지만, queue도 상속받았다.
Queue<String> que = new LinkedList<>();
que.offer("first");
que.offer("second");
/ 큐에서 데이터를 꺼낼 때는 2가지가 있다. /
✏️ 문제
* 설명
정보 왕국의 이웃 나라 외동딸 공주가 숲속의 괴물에게 잡혀갔습니다.
정보 왕국에는 왕자가 N명이 있는데 서로 공주를 구하러 가겠다고 합니다.
정보왕국의 왕은 다음과 같은 방법으로 공주를 구하러 갈 왕자를 결정하기로 했습니다.
왕은 왕자들을 나이 순으로 1번부터 N번까지 차례로 번호를 매긴다.
그리고 1번 왕자부터 N번 왕자까지 순서대로 시계 방향으로 돌아가며 동그랗게 앉게 한다.
그리고 1번 왕자부터 시계방향으로 돌아가며 1부터 시작하여 번호를 외치게 한다.
한 왕자가 K(특정숫자)를 외치면 그 왕자는 공주를 구하러 가는데서 제외되고 원 밖으로 나오게 된다.
그리고 다음 왕자부터 다시 1부터 시작하여 번호를 외친다.
이렇게 해서 마지막까지 남은 왕자가 공주를 구하러 갈 수 있다.
예를 들어 총 8명의 왕자가 있고, 3을 외친 왕자가 제외된다고 하자. 처음에는 3번 왕자가 3을 외쳐 제외된다.
이어 6, 1, 5, 2, 8, 4번 왕자가 차례대로 제외되고 마지막까지 남게 된 7번 왕자에게 공주를 구하러갑니다.
N과 K가 주어질 때 공주를 구하러 갈 왕자의 번호를 출력하는 프로그램을 작성하시오.
* 입력
첫 줄에 자연수 N(5<=N<=1,000)과 K(2<=K<=9)가 주어진다.
* 출력
첫 줄에 마지막 남은 왕자의 번호를 출력합니다.
🔍풀이
int index를 만들어, arrayList의 size와 같아지면 0으로 초기화 시켜서 Queue형태를 만들어줬다.
주의할 점은 remove를 하면 앞의 index가 하나씩 당겨오기 때문에, index--를 통해 다시 뒤로 돌려주어야 원래 순서가 맞게 된다.
public int solution(int a, int b) {
int answer = 0;
ArrayList<Integer> array = new ArrayList();
for(int i = 1; i <= a; i++){
array.add(i);
}
int cnt = 1;
int index = 0;
while(array.size() != 1){
cnt++;
index++;
if(index == array.size()) index = 0;
if(cnt % b == 0){
array.remove(index);
index--;
}
}
answer = array.get(0);
return answer;
}
🔍풀이
Queue를 이용해 앞의 원소를 뒤로 계속 보내준다.
public int solution(int a, int b) {
int answer = 0;
Queue<Integer> queue = new LinkedList();
for(int i = 1; i <= a; i++){
queue.offer(i);
}
int cnt = 0;
while(queue.size() != 1){
cnt++;
if(cnt % b != 0) queue.offer(queue.poll());
//맨앞 index의 값을 가장 뒤로 보내주는 작업
else queue.poll();
}
/* cnt 를 사용하지 않으면
for(int i = 1; i < a; i++) queue.offer(queue.poll());
// b번-1 만큼 앞 -> 뒤로 보내준 뒤
queue.poll(); // 제거 의 방법으로도 가능하다.
if(queue.size() == 1) answer = queue.poll();
*/
answer = queue.poll();
return answer;
}
* 설명
현수는 1년 과정의 수업계획을 짜야 합니다.
수업중에는 필수과목이 있습니다. 이 필수과목은 반드시 이수해야 하며, 그 순서도 정해져
있습니다.
만약 총 과목이 A, B, C, D, E, F, G가 있고, 여기서 필수과목이 CBA로 주어지면
필수과목은 C, B, A과목이며 이 순서대로 꼭 수업계획을 짜야 합니다.
여기서 순서란 B과목은 C과목을 이수한 후에 들어야 하고, A과목은 C와 B를 이수한 후에
들어야 한다는 것입니다.
현수가 C, B, D, A, G, E로 수업계획을 짜면 제대로 된 설계이지만
C, G, E, A, D, B 순서로 짰다면 잘 못 설계된 수업계획이 됩니다.
수업계획은 그 순서대로 앞에 수업이 이수되면 다음 수업을 시작하다는 것으로 해석합니다.
수업계획서상의 각 과목은 무조건 이수된다고 가정합니다.
필수과목순서가 주어지면 현수가 짠 N개의 수업설계가 잘된 것이면 “YES", 잘못된 것이면
”NO“를 출력하는 프로그램을 작성하세요.
* 입력
첫 줄에 한 줄에 필수과목의 순서가 주어집니다. 모든 과목은 영문 대문자입니다.
두 번 째 줄부터 현수가 짠 수업설계가 주어집니다.(수업설계의 길이는 30이하이다)
* 출력
첫 줄에 수업설계가 잘된 것이면 “YES", 잘못된 것이면 ”NO“를 출력합니다.
🔍풀이
Queue.contains를 이용해 필수과목인지 확인한다.
public String solution(String required, String plan){
String answer = "YES";
Queue<Character> Q = new LinkedList<>();
for(char c : required.toCharArray()) Q.offer(c);
for(char c : plan.toCharArray()){
if(Q.contains(c)){
//필수과목인 경우에만 서로 순서를 확인하고, 아닌 경우는 false로 넘겨버림.
if(c != Q.poll()) return "NO"; //아니면 NO같으면 다음으로.
}
}
//Q의 필수과목이 전부 이수되지 않은 경우 NO
if(!Q.isEmpty()) return "NO";
return answer;
}