DevLog ๐Ÿ“จ/Baekjoon

[DevLog][Baekjoon] 1655: ๊ฐ€์šด๋ฐ๋ฅผ ๋งํ•ด์š”

cece00 2023. 8. 20. 00:46

01) ๋ฌธ์ œ

๋ฐฑ์ค€์ด๋Š” ๋™์ƒ์—๊ฒŒ "๊ฐ€์šด๋ฐ๋ฅผ ๋งํ•ด์š”" ๊ฒŒ์ž„์„ ๊ฐ€๋ฅด์ณ์ฃผ๊ณ  ์žˆ๋‹ค. ๋ฐฑ์ค€์ด๊ฐ€ ์ •์ˆ˜๋ฅผ ํ•˜๋‚˜์”ฉ ์™ธ์น ๋•Œ๋งˆ๋‹ค ๋™์ƒ์€ ์ง€๊ธˆ๊นŒ์ง€ ๋ฐฑ์ค€์ด๊ฐ€ ๋งํ•œ ์ˆ˜ ์ค‘์—์„œ ์ค‘๊ฐ„๊ฐ’์„ ๋งํ•ด์•ผ ํ•œ๋‹ค. ๋งŒ์•ฝ, ๊ทธ๋™์•ˆ ๋ฐฑ์ค€์ด๊ฐ€ ์™ธ์นœ ์ˆ˜์˜ ๊ฐœ์ˆ˜๊ฐ€ ์ง์ˆ˜๊ฐœ๋ผ๋ฉด ์ค‘๊ฐ„์— ์žˆ๋Š” ๋‘ ์ˆ˜ ์ค‘์—์„œ ์ž‘์€ ์ˆ˜๋ฅผ ๋งํ•ด์•ผ ํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋ฐฑ์ค€์ด๊ฐ€ ๋™์ƒ์—๊ฒŒ 1, 5, 2, 10, -99, 7, 5๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ์™ธ์ณค๋‹ค๊ณ  ํ•˜๋ฉด, ๋™์ƒ์€ 1, 1, 2, 2, 2, 2, 5๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ ๋งํ•ด์•ผ ํ•œ๋‹ค. ๋ฐฑ์ค€์ด๊ฐ€ ์™ธ์น˜๋Š” ์ˆ˜๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ, ๋™์ƒ์ด ๋งํ•ด์•ผ ํ•˜๋Š” ์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค.

์ž…/์ถœ๋ ฅ

์ฒซ์งธ ์ค„์—๋Š” ๋ฐฑ์ค€์ด๊ฐ€ ์™ธ์น˜๋Š” ์ •์ˆ˜์˜ ๊ฐœ์ˆ˜ N์ด ์ฃผ์–ด์ง„๋‹ค. N์€ 1๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™๊ณ , 100,000๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ์ž์—ฐ์ˆ˜์ด๋‹ค. ๊ทธ ๋‹ค์Œ N์ค„์— ๊ฑธ์ณ์„œ ๋ฐฑ์ค€์ด๊ฐ€ ์™ธ์น˜๋Š” ์ •์ˆ˜๊ฐ€ ์ฐจ๋ก€๋Œ€๋กœ ์ฃผ์–ด์ง„๋‹ค. ์ •์ˆ˜๋Š” -10,000๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™๊ณ , 10,000๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™๋‹ค.

ํ•œ ์ค„์— ํ•˜๋‚˜์”ฉ N์ค„์— ๊ฑธ์ณ ๋ฐฑ์ค€์ด์˜ ๋™์ƒ์ด ๋งํ•ด์•ผ ํ•˜๋Š” ์ˆ˜๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ์ถœ๋ ฅํ•œ๋‹ค.

7
1
5
2
10
-99
7
5
// output is 1 1 2 2 2 2 5

02) ํ’€์ด

์ตœ๋Œ€ํž™๊ณผ ์ตœ์†Œํž™์„ ํ™œ์šฉํ•˜์—ฌ ์ค‘๊ฐ„๊ฐ’์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค. heap_push, heap_pop ์—ฐ์‚ฐ์—์„œ ๋ณด์•˜๋“ฏ์ด heap์„ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ •๊ฐ’์„ ๊ตฌํ•˜๊ณ ์ž ํ•  ๋•Œ๋Š” ์กฐ๊ฑด์ด ๋˜๋Š” ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ ๊ฐ’์„ push ๋˜๋Š” pop ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.

What is min heap and max heap?

ํž™(heap)์€ parent์™€ child๊ฐ€ ์ผ์ •ํ•œ ๋Œ€์†Œ๊ด€๊ณ„๋ฅผ ์œ ์ง€ํ•˜๋Š” ์ด์ง„ ํŠธ๋ฆฌ ๋ชจ์–‘์˜ ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค.

์ตœ์†Œ ํž™(min heap)์€ parent๊ฐ€ child๋ณด๋‹ค ์ž‘์•„์•ผ ํ•œ๋‹ค

์ตœ๋Œ€ ํž™(max heap)์€ parent๊ฐ€ child๋ณด๋‹ค ์ปค์•ผ ํ•œ๋‹ค

  1. min heap์˜ root๊ฐ€ max heap์˜ root๋ณด๋‹ค ํฌ๋‹ค
  2. ๋‘ heap์˜ ํฌ๊ธฐ๋ฅผ ๋น„๊ตํ•˜๋ฉด max๊ฐ€ 1 ํฌ๊ฑฐ๋‚˜, ์„œ๋กœ ๊ฐ™๋‹ค

์œ„์™€ ๊ฐ™์€ ์กฐ๊ฑด์„ ์œ ์ง€ํ•˜๋ฉด์„œ ๊ฐ’์„ push/popํ•˜๋ฉด max heap์˜ ๋ฃจํŠธ ๋…ธ๋“œ์—๋Š” ํ•ญ์ƒ ๋ฌธ์ œ์—์„œ ๊ตฌํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฐ’์ด ์œ„์น˜ํ•˜๊ฒŒ ๋จ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

  1. ํ˜„์žฌ๊นŒ์ง€ ๋ถˆ๋ฆฐ ์ˆ˜๊ฐ€ ์ง์ˆ˜์ธ ๊ฒฝ์šฐ: max heap๊ณผ min heap์˜ ๋ฃจํŠธ๊ฐ€ ์ค‘๊ฐ„๊ฐ’์ด๋‹ค. ๊ทธ ์ค‘ ๋” ์ž‘์€ max heap์˜ ๋ฃจํŠธ ์„ ํƒ
  2. ํ˜„์žฌ๊นŒ์ง€ ๋ถˆ๋ฆฐ ์ˆ˜๊ฐ€ ํ™€์ˆ˜์ธ ๊ฒฝ์šฐ: max heap์˜ ํฌ๊ธฐ๊ฐ€ 1 ํฌ๋ฏ€๋กœ, max heap์˜ ๋ฃจํŠธ๊ฐ€ ์ค‘๊ฐ„๊ฐ’์ด๋‹ค
# pseudo

max_heap, min_heap

new = int(input()) # ์ƒˆ๋กœ ์™ธ์นœ ์ •์ˆ˜

# ๋งŒ์•ฝ max heap์ด 1 ๋” ํฌ๋‹ค๋ฉด, min heap์— ๋„ฃ์–ด balance๋ฅผ ์œ ์ง€ํ•œ๋‹ค
if max_heap.size > min_heap.size:
  min_heap.push(new)
# ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด, max heap์— ๋„ฃ๋Š”๋‹ค
else:
  max_heap.push(new)

# ๋งŒ์•ฝ max heap์˜ ๋ฃจํŠธ๊ฐ€ min heap์˜ ๋ฃจํŠธ๋ณด๋‹ค ํฌ๋ฉด
# ์–‘์ชฝ ๋ชจ๋‘๋ฅผ pop ํ•˜๋ฉฐ swapํ•ด push ํ•ด์ค€๋‹ค
if max_heap.root > min_heap.root:
  larger = max_heap.pop()
  min_heap.push(larger) # ๊บผ๋‚ธ ๊ฐ’์„ pushํ•˜์—ฌ ๋‹ค์‹œ min heap์ด ์ •๋ ฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค

  smaller = min_heap.pop()
  max_heap.push(smaller)

heap์— push์™€ pop์„ ํ•˜๋Š” ์—ฐ์‚ฐ์€ ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ O(logN)์ด๋‹ค. ๋‹ต์•ˆ์—๋Š” heapq ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ, ์ฒ˜์Œ์—๋Š” min/max heap์„ ๋ฐฐ์—ด๋กœ ์žก์€ ํ›„, compare ํ•จ์ˆ˜์™€ ๊ฐ heap ๋ฐฐ์—ด์„ ์ธ์ž๋กœ ๋ฐ›์•„ push/pop์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ์—ˆ๋‹ค. ๋ฌธ์ œ ์˜ˆ์‹œ ์ •๋„๋Š” ๊ฐ€๋ณ๊ฒŒ ์ •๋‹ต์„ ๋ฑ‰์—ˆ์ง€๋งŒ, ์‹ค์ œ ์ฑ„์  ๊ฒฐ๊ณผ๋Š” ์‹œ๊ฐ„์ดˆ๊ณผ ๊ฐ€ ๋‚˜์™”๋‹ค. ํŒŒ์ด์ฌ list์˜ ๋‚ด์žฅํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ณผ์ •์—์„œ ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ ์ฆ๊ฐ€ํ•œ ๊ฒƒ ๊ฐ™๊ณ , heapq ๋ชจ๋“ˆ์€ list๊ฐ€ ์•„๋‹Œ C์˜ array๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”๋ชจ๋ฆฌ/์„ฑ๋Šฅ๋ฉด์—์„œ ๋‚ซ๋‹ค๊ณ  ํ•œ๋‹ค.

heapq๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž๋™์œผ๋กœ min heap ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•ด ์ค€๋‹ค. max heap์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋Š” ์›์†Œ์— * -1์„ ์ทจํ•˜์—ฌ pushํ•ด ์ฃผ๋ฉด ๋œ๋‹ค.

๐Ÿ“ฃ Python List Function Complexity

Operation Example TC Notes
Index list[i] O(1)
Store list[i] = 0 O(1)
Length len(list) O(1)
Append list.append(5) O(1)
Pop list.pop() O(1) ๋งˆ์ง€๋ง‰ ์›์†Œ ์ œ๊ฑฐ
Clear list.clear() O(1) list = []
Slice list[a:b] O(b-a)
Extend list.extend(...) O(len(...))
Construction list(...) O(len(...))
Cheak Equal list1 == list2 O(N)
Insert list[a:b] = ... O(N)
Delete del list[i] O(N)
Containment x in/not in list O(N)
Copy list.copy() O(N)
Remove list.remove(...) O(N)
Pop list.pop(i) O(N) ํŠน์ • ์ธ๋ฑ์Šค ์›์†Œ ์ œ๊ฑฐ
Extreme value min(list)/max(list) O(N)
Reverse list.reverse() O(N)
Iteration for v in list: O(N)
Sort list.sort() O(N Log N)
Multiply k*list O(k N)

03) ์ฝ”๋“œ(ํŒŒ์ด์ฌ)


import sys
import heapq


N = int(input())
X = [int(sys.stdin.readline()) for _ in range(N)]
minH = []
maxH = []


for i in range(N):
    n = X[i]
    if i == 0:
        heapq.heappush(maxH, -n)  # max heap
        print(-maxH[0])
        continue

    elif len(minH) == len(maxH):
        heapq.heappush(maxH, -n)

    else:
        heapq.heappush(minH, n)

    if -maxH[0] > minH[0]:
        minroot = heapq.heappop(minH)
        heapq.heappush(maxH, -minroot)
        maxroot = heapq.heappop(maxH)
        heapq.heappush(minH, -maxroot)

    print(-maxH[0])