๐Ÿ’ซ ETC/Leetcode

Week 3-2. [Heap] 215. Kth Largest Element in an Array (Python3)

ming412 2023. 9. 12. 09:42

๋ฌธ์ œ ํ•ด๊ฒฐ ๊ณผ์ •

โœ๏ธ ๋ฌธ์ œ ์š”์•ฝ

https://leetcode.com/problems/kth-largest-element-in-an-array/?envType=study-plan-v2&envId=top-interview-150 

 

Kth Largest Element in an Array - LeetCode

Can you solve this real interview question? Kth Largest Element in an Array - Given an integer array nums and an integer k, return the kth largest element in the array. Note that it is the kth largest element in the sorted order, not the kth distinct eleme

leetcode.com

โžก๏ธ ์ฃผ์–ด์ง„ ๋ฐฐ์—ด์„ ์ •๋ ฌํ•˜์ง€ ์•Š๊ณ  k๋ฒˆ์งธ๋กœ ํฐ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ผ.

 

๐Ÿ”Ž ์–ด๋–ค ์‹์œผ๋กœ ์ ‘๊ทผํ–ˆ๋Š”๊ฐ€?

์ •๋ ฌ์„ ํ•˜์ง€ ๋ง๋ผ๋Š” ์š”๊ตฌ์‚ฌํ•ญ์ด ์žˆ์—ˆ์œผ๋ฏ€๋กœ ์ตœ๋Œ€ํž™์„ ์‚ฌ์šฉํ•˜์ž.

 

์šฐ์„  ํŒŒ์ด์ฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ํž™ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด ํ’€์–ด๋ณด๊ณ , ํž™์„ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์„œ๋„ ํ’€์–ด๋ณผ ๊ฒƒ์ด๋‹ค.

ํŒŒ์ด์ฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ํž™ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ตœ์†Œํž™์ด๊ธฐ ๋•Œ๋ฌธ์— ๋งˆ์ด๋„ˆ์Šค ๊ธฐํ˜ธ๋ฅผ ์ด์šฉํ•ด ์ตœ๋Œ€ํž™์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

ํž™์„ ์ง์ ‘ ๊ตฌํ˜„ํ•  ๋•Œ๋Š” push์™€ pop์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š”๋ฐ, ๊ฐ๊ฐ์—์„œ ์‚ฌ์šฉ๋˜๋Š” bubbleUp๊ณผ bubbleDown ๋กœ์ง์ด ํ•ต์‹ฌ์ด๋‹ค.

 

๐ŸŽฏ ํ’€์ด

ํŒŒ์ด์ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•œ ํ’€์ด์ด๋‹ค.

import heapq as hq
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        lst = [] # ํž™์„ ๋ชจ๋ฐฉํ•  ๋ฆฌ์ŠคํŠธ

        for x in nums:
            hq.heappush(lst, -x) # ์ตœ๋Œ€ํž™

        ans = 0
        for x in range(k):
            ans = -hq.heappop(lst)
        return ans

 

ํž™์„ ์ง์ ‘ ๊ตฌํ˜„ํ•˜์—ฌ ์‚ฌ์šฉํ•œ ํ’€์ด์ด๋‹ค.

class Heap:
    def __init__(self):
        self.array = []
        self.numberOfItems = 0
    
    def push(self, e: int) -> None:
        self.array.append(e) # ์ƒˆ๋กœ์šด ์š”์†Œ๋ฅผ ๋งจ ๋งˆ์ง€๋ง‰์— ์ €์žฅ
        self.bubbleUp(self.numberOfItems) # Heap์˜ ๋งจ ๋งˆ์ง€๋ง‰ ์š”์†Œ์ธ array[numberOfItems]๋ถ€ํ„ฐ bubble Up!
        self.numberOfItems += 1

    def bubbleUp(self, i: int) -> None:
        child, parent = i, (i-1)//2
        if parent >= 0 and self.array[child] > self.array[parent]:
            self.array[child], self.array[parent] = self.array[parent], self.array[child] # swap
            self.bubbleUp(parent)
    
    def pop(self) -> int:
        mx = self.array[0]
        self.array[0] = self.array[self.numberOfItems-1] # ๋งˆ์ง€๋ง‰ ์š”์†Œ๋ฅผ 0๋ฒˆ์งธ ์ธ๋ฑ์Šค์— ์ €์žฅ
        self.numberOfItems -= 1
        self.bubbleDown(0) # # Heap์˜ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ์ธ array[0]๋ถ€ํ„ฐ bubble Down!
        return mx

    def bubbleDown(self, i: int) -> None: # i๋Š” ๋ถ€๋ชจ ์ธ๋ฑ์Šค
        left, right = 2*i+1, 2*i+2 # ์™ผ์ชฝ ์ž์‹, ์˜ค๋ฅธ์ชฝ ์ž์‹
        if left <= self.numberOfItems - 1:
            # ๋‘˜ ์ค‘ ๋” ํฐ ์ž์‹ ์„ ํƒ
            if right <= self.numberOfItems and self.array[right] > self.array[left]:
                left = right
            # ์œ„์—์„œ ์„ ํƒ๋œ ์ž์‹์ด ๋ถ€๋ชจ๋ณด๋‹ค ํฌ๋‹ค๋ฉด swap
            if self.array[i] < self.array[left]:
                self.array[i], self.array[left] = self.array[left], self.array[i] # swap
                self.bubbleDown(left)

class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        heap = Heap()
        for x in nums:
            heap.push(x)
        ans = 0
        for i in range(k):
            ans = heap.pop()
        return ans

 

๋‹ค๋ฅธ ์‚ฌ๋žŒ์˜ ์ฝ”๋“œ๋ฅผ ํƒ๊ตฌํ•ด๋ณด๊ธฐ

ํŒŒ์ด์ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•œ ํ’€์ด์ด๋ฉฐ heapify()๋ฅผ ์‚ฌ์šฉํ•ด ๊ธฐ์กด nums ๋ฆฌ์ŠคํŠธ๋ฅผ ์ตœ์†Œํž™์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ด์šฉํ•œ๋‹ค. 

import heapq as hq
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        hq.heapify(nums) # nums๋ฅผ ์ตœ์†Œํž™์œผ๋กœ ๋ณ€ํ™˜
        amount = len(nums)
        
        while amount > k:
            hq.heappop(nums)
            amount -= 1
            
        return nums[0]