num1, num2 : 입력되는 배열 ()
m, n : 2개의 배열 각각의 길이 ()
크기가 각각 m, n이면서 정수가 정렬된 상태로 입력되는 2개의 배열이 있을 때, 2개의 정렬된 배열을 합치고 중앙값을 반환하는 문제이다.
단, 시간복잡도가 반드시 이어야만 한다.
중앙값이란,
표본이 가지고 있는 수치를 오름차순 정렬했을 때 가장 중앙에 오는 숫자를 의미하며
1. 표본수가 홀수 → 중앙에 있는 숫자
2. 표본수가 짝수 → 중앙의 좌, 우 2개 숫자의 평균
으로 계산한다.
첫번째 아이디어
+ 연산으로 합치기sort()로 정렬두번째 아이디어 → ✅ 채택
배열을 절반으로 나눠 분할 위치를 결정한다.
num1, num2 각각 i, j 위치를 정해 나누기i + j = (m + n + 1) // 2 : 전체 길이의 절반i 감소i 증가2개의 배열 각각 이진 탐색 →
최종 시간복잡도
이므로 조건 를 만족한다.
sort()로 정렬하고 이진 탐색하기class Solution:
def findMedianSortedArrays(self, nums1: list[int], nums2: list[int]) -> float:
# 길이 비교해 더 짧은 배열을 nums1으로 두기
if len(nums1) > len(nums2):
nums1, nums2 = nums2, nums1
# 길이 저장 변수 정의
m, n = len(nums1), len(nums2)
# 왼쪽, 오른쪽 정의
left, right = 0, m
# 이진탐색 시작
while left <= right:
# nums1은 i, nums2는 j에서 자르기
i = (left + right) // 2
j = (m + n + 1) // 2 - i
# 최솟값, 최댓값 지정
max_left_nums1 = float('-inf') if i == 0 else nums1[i-1]
min_right_nums1 = float('inf') if i == m else nums1[i]
max_left_nums2 = float('-inf') if j == 0 else nums2[j-1]
min_right_nums2 = float('inf') if j == n else nums2[j]
# 잘 분할되었는지 확인
if max_left_nums1 <= min_right_nums2 and max_left_nums2 <= min_right_nums1:
# 홀수라면 중앙값 반환
if (m + n) % 2 == 1:
return max(max_left_nums1, max_left_nums2)
# 짝수라면 평균
else:
return (max(max_left_nums1, max_left_nums2) + min(min_right_nums1, min_right_nums2)) / 2
# 잘 분할 안되었다면 이동
elif max_left_nums1 > min_right_nums2:
right = i - 1
else:
left = i + 1

class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
# 두 배열 합치기
nums3 = nums1 + nums2
# 배열 오름차순 정렬
nums3.sort()
# 길이가 짝수면 평균으로 구하기
if len(nums3)%2 == 0:
mid = int(len(nums3) / 2)
total = nums3[mid]+nums3[mid-1]
median = total / 2
# 길이가 홀수면 중앙값 바로 구하기
else:
mid = len(nums3) // 2
median = nums3[mid]
return median