PriorityQueue 사용
💬 알고리즘 문제에서 저장한 데이터를 우선순위에 따라 추출해야 했습니다. 이 경우 가장 먼저 떠오르는 것이 우선순위 큐(Heap)였습니다. Java에서 제공하는 자료구조였기에 쉽게 적용해 볼 수 있었습니다.
✔ 메커니즘
💬 Java에서 제공하는 PriorityQueue는 Comparator를 지정하지 않으면 제너릭에 입력한 타입의 Comparator 가져다가 씁니다. 이번에는 Integer를 사용했기 때문에 숫자의 크기에 따라 우선순위가 정해졌습니다.
✔ 절댓값 크기로 우선순위 정하기
💬 문제에서 절댓값 크기와 절댓값이 같은 경우 숫자의 크기로 우선순위가 정해져야 했습니다. Integer Comparator를 사용하면 원하는 우선순위를 얻을 수 없습니다. 별도의 Comparator를 정의해야 했으며, 이를 위해 어떻게 동작하는지 파악할 필요가 있었습니다.
✔ PriorityQueue 우선순위가 정해지는 메커니즘
💬 Comparator를 정의해 주는 경우 내부적으로 siftUpUsingComprator 메서드에서 우선순위 기반으로 데이터를 저장합니다. 우선순위 큐는 부모 노드가 자식 노드보다 우선순위가 높기 때문에 부모와 자식 노드의 비교를 통해 데이터의 위치를 정할 수 있습니다. 여기서 우선순위가 높은 지를 체크하는 부분은 "cmp.compare(x, (T) e) >= 0"이었습니다. 두 값을 비교했을 때 음수 값이 나와야 새로운 데이터가 우선순위가 높다고 판단을 하고 있었습니다.
private static <T> void siftUpUsingComparator( int k, T x, Object[] es, Comparator<? super T> cmp) { while (k > 0) { int parent = (k - 1) >>> 1; Object e = es[parent]; if (cmp.compare(x, (T) e) >= 0) break; es[k] = e; k = parent; } es[k] = x; }
✔ Comparator 적용
💬 위 로직 확인을 통해 우선순위를 높게 하려면 비교했을 때 음수 값이 나와야 한다는 것을 알았습니다. 이를 기반으로 코드를 작성해 보면 아래와 같습니다.
➡ 절댓값이 작을 경우 우선순위가 더 높다.
➡ 절댓값이 같은 경우 실제 값이 작은 경우 우선순위가 더 높다.
Queue queue = new PriorityQueue<Integer>((Integer a, Integer b) -> compare(a,b)); public static int compare(Integer first, Integer second) { if(abs(first) == abs(second)) { return first < second ? -1 : 1; } return abs(first) < abs(second) ? -1 : 1; }
'개발일지 > TIL' 카테고리의 다른 글
[231022] Mybatis 파라미터 #과 $의 차이 (1) | 2023.10.22 |
---|---|
[231008] JWT는 어디에 저장을 해야할까? (0) | 2023.10.08 |
[230913] Scale-out 환경에서 Scheduler 중복으로 실행되는 문제 (0) | 2023.09.13 |
[230901] 간단한 화면 구현 (0) | 2023.09.01 |
[230830] 서버간 통신을 위해 Kafka 적용 (0) | 2023.08.30 |