오늘의 학습 키워드
</> 스택/큐
공부한 내용 본인의 언어로 정리하기
import java.util.*;
class Solution {
public int solution(int[] priorities, int location) {
//Key와 Value로 인덱스와 우선순위를 관리해야해서 추가/삭제가 편한 LinkedList이용
Queue<int[]> queue = new LinkedList<>();
//우선순위 크기 순서로 정렬(내림차순으로 정렬을 해야 앞쪽이 우선순위가 높은 값이 옴)
PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
//큐와 우선순위 초기화
for(int i = 0; i < priorities.length; i++){
// 큐에 [인덱스, 우선순위] 형태로 저장
queue.offer(new int[]{i, priorities[i]});
// 우선순위 큐에 우선순위 저장
pq.offer(priorities[i]);
}
int order = 0; //실행 순서 카운트
//queue가 다 비어있을때 까지 반복
while(!queue.isEmpty()){
int[] current = queue.poll(); //큐에서 프로세스 하나 꺼내기
//꺼낸 프로세스가 우선 순위가 높은 값인지 비교
if(current[1] == pq.peek()){
order++; // 실행 순서 증가
pq.poll();//우선 순위 큐에서 해당 우선순위 제거
//location의 순서 구하기
if(current[0] == location){
return order;
}
} else {
// 우선 순위가 더 높은 프로세스가 있다면 다시 큐에 넣기
queue.offer(current);
}
}
return 0;
}
}
오늘의 회고
다시 스택/큐 문제가 나오면서 아직 문법에 대해서 모르는게 많다는게 크게 다가온 하루였다.
아직 알아야할게 너무 많고 부족하다.
일단은 오늘 문제 풀이를 시작해보겠다.
오늘도 대략 1시간 정도 고민을 하면서 큰 값부터 뽑아 낼 수 있는 우선순위 큐
랑 Key
와 Value
를 활용해서 순서를 저장하고 이용하면 좋겠다라고 생각했고 이것을 활용할 방법을 찾았다.
그래서 일단 위의 2개를 만들어주었다.
스택/큐 문제였기 때문에 큐와 우선순위 큐를 만들어 주었다.
알아보다 보니 LinkedList
가 추가/삭제가 쉽다고 보았고 priorities
값에 Key
를 부여해주어야 겠다고 생각했기 때문에 아래와 같이 만들었다.
Queue<int[]> queue = new LinkedList<>();
PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
이후 priorities
값에 key
를 부여해줘서 초기화를 시켜준다.
그리고 우선순위 큐에 우선순위를 저장해준다.
for(int i = 0; priorities.length; i++){
queue.offer(new int[]{i, priorities[i]});
pq.offer(priorities[i]);
}
이제 운영체제가 프로세스를 관리하는 규칙에 따라 메인루프를 만들어야 한다.
그래서 queue
가 모두 제거될 때 까지 반복해서 순서를 구하고 검증하는 것들이 필요했다.
while(!queue.isEmpty()){
}
매번 현재 큐를 비교해서 진행해야하기 때문에 queue
의 값을 꺼내서 넣어줄 current
객체를 하나 만들어 준다.
int[] current = queue.poll();
꺼낸 큐가 우선순위에 pq
에서 가장 높은 값인지 검증하고 맞다면 우선 순위 큐에서 해당 큐를 제거하고 아니라면 다시 큐에 넣어준다.
if(current[1] == pq.peek()){
pq.poll();
} else {
queue.offer(current);
}
진행 순서는 완료 되었고, location
의 순서를 구하기 위해서 코드를 추가해 준다.
int order = 0;
검증하는 if
문 안에 실행순서를 증가 시키고 현재값이 location
과 같다면 순서를 반환하주는 방식으로 진행하도록 했다.
if(current[1] == pq.peek()){
order++;
pq.poll();
}
if(current[0] == location){
return order;
}
그리고 마지막에는 컴파일을 위해서 return
을 할 필요가 있었는데 이 값을 임의로 0으로 설정해 주었다. 하지만 지금 회고하면서 생각해보니 해당될 수 없는 값인 음수로 해놓았으면 어땠을까 생각이 든다.
AI 코드리뷰
현재 코드의 장점
LinkedList
와 PriorityQueue
를 적절히 사용하여 문제를 해결하고 있습니다.현재 코드의 단점
PriorityQueue
를 전체 우선순위에 대해 생성하고 있어, 메모리 사용량이 다소 높을 수 있습니다.PriorityQueue
의 peek()
연산을 수행하고 있어, 약간의 성능 저하가 있을 수 있습니다.시간 복잡도
import java.util.*;
class Solution {
public int solution(int[] priorities, int location) {
Queue<int[]> queue = new LinkedList<>();
for(int i = 0; i < priorities.length; i++){
queue.offer(new int[]{i, priorities[i]});
}
Arrays.sort(priorities); // 우선순위 정렬
int order = 0;
while(!queue.isEmpty()){
int[] current = queue.poll();
if(current[1] == priorities[priorities.length - 1 - order]){
order++;
if(current[0] == location){
return order;
}
} else {
queue.offer(current);
}
}
return 0;
}
}
개선된 버전의 장점
Queue<int[]>
를 사용하여 데이터 타입의 안정성을 높였습니다.개선된 버전의 단점
Arrays.sort
를 사용하여 우선순위를 정렬하므로 O(n log n)
의 추가 비용이 발생합니다.시간 복잡도
내일 공부할 것 :
내일 스택과 큐에 대해서 정리해서 기록을 해야되겠다. 스택과 큐 안에서도 여러가지 기능이 있는 것으로 알고있고 오늘 공부하면서 태블릿에 살짝 정리해 놓은것도 있는데 생각보다 많이 커질거 같다.
문제
https://school.programmers.co.kr/learn/courses/30/lessons/42587