[HackerRank] Find the Running Median (Python)

2025. 1. 18. 21:18·코딩 테스트
728x90

1. 문제

https://www.hackerrank.com/challenges/find-the-running-median/problem

 

2. 풀이

처음엔 a의 길이가 홀수, 짝수 케이스로 나누어서 단순히 중위값을 구하려고했다.

참고로 python에서 n / 2 를 하면 실수를 반환하지만 n//2를 하면 int 정수를 반환한다.

def runningMedian(a):
    answer = []
 
    for i in range(1, len(a)+1):
        li = sorted(a[:i])
        n = len(li)
        
        # odd
        if (n % 2 != 0):
            median = li[n // 2]
        else:
            median = (li[n // 2] + li[(n // 2) - 1]) / 2

        answer.append(median)

    return answer

 

하지만 위 코드의 시간복잡도는 

정렬(sorted)은 O(k log k), 여기서 k는 배열의 길이, 총 n번 반복하므로 시간 복잡도는 O(n² log n) 이다.

 

heap 을 이용해야 시간복잡도를 줄일 수 있는 문제. Heap을 사용하면 시간 복잡도를 O(nlogn)으로 줄일 수 있다.

- left heap : 중위값보다 작은 값을 저장

- right heap : 중위값보다 큰 값을 저장

heap 의 insert , delete 가 O(logN) 이므로 n 번 반복하면 O(nlogn) 이다.

 

중위값을 구할 때, 왼쪽 힙이 더 크거나 두 힙의 크기가 같으면 왼쪽 힙의 루트가 중위값이고, 그렇지 않으면 두 힙의 루트를 평균하여 중위값을 구합니다.

2개의 heap 을 사용하므로 공간 복잡도는 O(N) 이다.

 

import heapq 필요!!!

 

3.코드

import heapq

def runningMedian(a):
    # 두 개의 힙을 사용할 것: 
    # max heap (left)와 min heap (right)
    left = []  # max heap (파이썬은 기본적으로 min heap이라 음수로 값 저장)
    right = []  # min heap
    
    result = []
    
    for num in a:
        # 새로운 숫자가 들어오면 두 힙 중 적절한 곳에 추가
        if len(left) == 0 or num <= -left[0]:
            heapq.heappush(left, -num)  # max heap에 삽입 (음수로 저장)
        else:
            heapq.heappush(right, num)  # min heap에 삽입
        
        # 두 힙의 크기 균형 맞추기
        if len(left) > len(right) + 1:
            # 왼쪽 힙이 너무 크면, 왼쪽에서 하나를 오른쪽으로 이동
            heapq.heappush(right, -heapq.heappop(left))
        elif len(right) > len(left):
            # 오른쪽 힙이 너무 크면, 오른쪽에서 하나를 왼쪽으로 이동
            heapq.heappush(left, -heapq.heappop(right))
        
        # 중위값 계산
        if len(left) > len(right):
            # 왼쪽 힙이 더 크면, 중위값은 왼쪽 힙의 루트
            result.append(float(-left[0]))
        else:
            # 두 힙의 크기가 같으면, 중위값은 두 힙의 루트의 평균
            result.append((-left[0] + right[0]) / 2.0)
    
    return result

 

  • left (max heap):
    • heapq는 기본적으로 min heap을 사용하므로, 중위값보다 작은 값들은 음수로 저장하여 max heap처럼 동작하도록 합니다.
  • right (min heap):
    • heapq에서 기본적으로 제공하는 min heap을 그대로 사용하여 중위값보다 큰 값들을 저장합니다.
  • 두 힙의 크기 균형:
    • 두 힙의 크기가 너무 차이나지 않도록, 힙이 한쪽으로 치우칠 경우 크기가 큰 힙에서 하나를 작은 힙으로 이동시킵니다.
  • 중위값 계산:
    • left 힙의 크기가 right 힙보다 크면 left 힙의 루트가 중위값입니다.
    • 두 힙의 크기가 같으면 두 힙의 루트 값을 평균으로 계산합니다.

 

 

728x90
저작자표시 비영리 변경금지 (새창열림)

'코딩 테스트' 카테고리의 다른 글

[LeetCode] 202. Happy Number (Python)  (0) 2025.01.27
[HackerRank] Contacts (Python)  (0) 2025.01.18
[HackerRank] Tree: Level Order Traversal  (0) 2025.01.18
[HackerRank] Tree: Height of a Binary Tree (Python)  (0) 2025.01.18
[HackerRank] Balanced Brackets (Python)  (0) 2025.01.18
'코딩 테스트' 카테고리의 다른 글
  • [LeetCode] 202. Happy Number (Python)
  • [HackerRank] Contacts (Python)
  • [HackerRank] Tree: Level Order Traversal
  • [HackerRank] Tree: Height of a Binary Tree (Python)
zoodi
zoodi
IT/개발 관련 지식을 기록하는 블로그입니다.
  • zoodi
    오늘의 기록
    zoodi
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 후기
        • 컨퍼런스
        • 일상리뷰
      • 금융경제
        • 뉴스
        • 금융IT용어
        • 경제 및 부동산
      • 코딩 테스트
      • 스터디
        • JAVA
        • Kotlin
        • Spring
        • React, Nextjs
        • 인공지능 AI
        • Cloud & k8s
        • Kafka
        • Database
        • Network
        • Algorithm
        • Hadoop
        • LINUX
        • R Programming
        • 기타 (소공, 보안)
      • 도서
      • 기타
  • 블로그 메뉴

    • 홈
    • 스터디
    • 금융경제
    • 후기
    • 기타
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    스프링
    네트워크
    Python
    쿠버네티스
    리트코드
    알고리즘
    카카오코테
    자료구조
    스프링부트
    자바
    MySQL
    코테공부
    LeetCode
    Spring
    코딜리티
    이분탐색
    springboot
    pythoncodingtest
    CodingTest
    코테
    프로그래머스
    코딩테스트
    kafka
    java
    C++
    금융용어
    코딩
    Kotlin
    codility
    db
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
zoodi
[HackerRank] Find the Running Median (Python)
상단으로

티스토리툴바