[코테 스터디 10일차 TIL] Kth Largest Element in a Stream

dev_jubby·2024년 7월 31일
1

코테스터디

목록 보기
10/36



💛 오늘의 학습 키워드

[힙(Heap)] Kth Largest Element in a Stream



📝 문제

문제 설명

Design a class to find the kthk^{th} largest element in a stream. Note that it is the kthk^{th} largest element in the sorted order, not the kthk^{th} distinct element.

Implement KthLargest class:

KthLargest(int k, int[] nums) Initializes the object with the integer k and the stream of integers nums.
int add(int val) Appends the integer val to the stream and returns the element representing the kthk^{th} largest element in the stream.

제한 조건

  • 1 <= k <= 10410^4
  • 0 <= nums.length <= 10410^4
  • 104-10^4 <= nums[i] <= 10410^4
  • 10410^4 <= val <= 10410^4
  • At most 10410^4 calls will be made to add.
  • It is guaranteed that there will be at least k elements in the array when you search for the kthk^{th} element.

입출력 예

Input
["KthLargest", "add", "add", "add", "add", "add"][3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]]
Output
[null, 4, 5, 5, 8, 8]
Explanation

KthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]);
kthLargest.add(3);   // return 4
kthLargest.add(5);   // return 5
kthLargest.add(10);  // return 5
kthLargest.add(9);   // return 8
kthLargest.add(4);   // return 8



💬 내 풀이

class KthLargest {
     // 우선순위 큐 선언
    PriorityQueue<Integer> pq = new PriorityQueue<>();

    int size = 0;

    public KthLargest(int k, int[] nums) {
        size =  k;

        // nums[] 을 우선순위 큐에 넣고, 큐보다 k값이 크면 마지막 요소 제거
        for (int n : nums) {
            pq.offer(n);
            if(pq.size() > k) pq.poll();
        }
    }

    public int add(int val) {
        // val 값을 우선순위 큐에 추가
        pq.offer(val);
        if(pq.size() > size) pq.poll();
        return pq.peek();
    }
}

💻 내 접근 방법

  1. 먼저 우선순위 큐 객체를 생성한다.

    • PriorityQuere : 일반적인 큐의 구조(FIFO)를 가지면서, 우선순위를 먼저 결정하고, 높은 데이터가 먼저 나가는 자료구조이다.

우선순위 큐 선언

// 높은 우선순위의 요소를 먼저 처리하는 큐 선언
PriorityQuere<Integer> pq = new PriorityQueue<>(); 
// 낮은 우선순위의 요소를 먼저 처리하는 큐 선언
PriorityQuere<Integer> pq = new PriorityQueue<>()Collections.reverseOrder(); 
  1. k번째로 큰 요소를 꺼내기 위해 size를 전역변수로 선언한다.
  2. KthLargest() 에서는 ksize에 넣어주고, nums[] 데이터를 pq에 넣어준다.
    • 여기서 k 보다 pq의 크기가 크면 poll() 메소드를 사용해서 큰 숫자부터 삭제하여 kpq의 크기가 항상 같게 만들어준다.
  3. add() 는 똑같이 offer()를 사용하여 val 값을 추가한 후 동일하게 큰 요소는 삭제한다.
  4. k번째로 큰 요소를 꺼내기 위해 peek() 메소드를 사용하여 꺼내어 return 한다.



✨ 다른 사람 풀이

class KthLargest {
    private static int k;
    private PriorityQueue<Integer> heap;
    
    public KthLargest(int k, int[] nums) {
        this.k = k;
        heap = new PriorityQueue<>();
        
        for (int num: nums) {
            heap.offer(num);
        }
        
        while (heap.size() > k) {
            heap.poll();
        }
    }
    
    public int add(int val) {
        heap.offer(val);
        if (heap.size() > k) {
            heap.poll();
        }

        return heap.peek();
    }
}
  1. int size 로 선언하지 않고,this 를 사용하면 되는 것이었다..!

💦 회고

k번째로 큰 값을 뽑아낸다는 것 = 크기를 k만큼으로 유지한 후 제일 큰 값을 뽑아낸다. 라는 걸 깨닫는데 오래걸렸다.. 머리가 말랑말랑해졌으면 좋겠다.




참고
https://hyojun.tistory.com/entry/LeetCode-703-Kth-Largest-Element-in-a-Stream-Java
https://velog.io/@gillog/Java-Priority-Queue우선-순위-큐

profile
신입 개발자 쥬비의 기술 블로그 입니다.

0개의 댓글