본문 바로가기

백엔드/알고리즘, 자료구조

합병 정렬

반응형

** 개요

 

 

** 설명

크게 작은 단위로 나누어서, 

위로 올라오며 합치는 방식이라고 생각하시면 됩니다.

예시 )

[1, 2, 3, 5]  # 정렬된 배열 A
[4, 6, 7, 8]  # 정렬된 배열 B
[] # 두 집합을 합칠 빈 배열 C

        ↓
1단계 : [**1**, 2, 3, 5] 
        ↓
       [**4**, 6, 7, 8] 
        1과 4를 비교합니다!
        1 < 4 이므로 1을 C 에 넣습니다.
     C:[1]

           ↓
2단계 : [1, **2**, 3, 5] 
        ↓
       [**4**, 6, 7, 8] 
        2와 4를 비교합니다!
        2 < 4 이므로 2를 C 에 넣습니다.
     C:[1, 2]

              ↓
3단계 : [1, 2, **3**, 5] 
        ↓
       [**4**, 6, 7, 8] 
        3과 4를 비교합니다!
        3 < 4 이므로 3을 C 에 넣습니다.
     C:[1, 2, 3]

                 ↓
3단계 : [1, 2, 3, **5**] 
        ↓
       [**4**, 6, 7, 8] 
        5와 4를 비교합니다!
        5 > 4 이므로 4을 C 에 넣습니다.
     C:[1, 2, 3, 4]

                 ↓
3단계 : [1, 2, 3, **5**] 
           ↓
       [4, **6**, 7, 8] 
        5와 6을 비교합니다!
        5 < 6 이므로 5을 C 에 넣습니다.
     C:[1, 2, 3, 4, 5]

엇, 이렇게 되면 A 의 모든 원소는 끝났습니다!

그러면 B에서 안 들어간 원소인
       [6, 7, 8] 은 어떡할까요?
하나씩 C 에 추가해주면 됩니다.
     C:[1, 2, 3, 4, 5, 6, 7, 8] 이렇게요!

그러면 A 와 B를 합치면서 정렬할 수 있었습니다.

** 구현

from typing import List


class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        #쪼개고
        def splice(lst):
            if len(lst) <= 1:
                return lst
            mid = len(lst) //2
            L = lst[:mid]
            R = lst[mid:]
            oneL = splice(L)
            oneR = splice(R)
            sorted_lst = sort_pieces(oneL, oneR)
            return sorted_lst
        #쪼갠 걸 정렬하며 합친다
        #[8], [4,5]
        def sort_pieces(oneL, oneR):
            i = 0
            j = 0
            new = []
            while i < len(oneL) and j < len(oneR):
                if oneL[i] < oneR[j]:
                    new.append(oneL[i])
                    i+=1
                else:
                    new.append(oneR[j])
                    j += 1

            while j == len(oneR) and i < len(oneL):
                new.append(oneL[i])
                i += 1

            while i == len(oneL) and j < len(oneR):
                new.append(oneR[j])
                j+=1
            return new

        return splice(intervals)


aa = Solution()
print(aa.merge([[1,3],[2,6],[8,10],[15,18]]))

 

** 시간 복잡도

 

위의 케이스에서 보듯이, 각각의 레벨에서는 N만큼 탐색을 합니다.

그 이유는 ,

계속 절반으로 나누면 그 절반들을 서로 비교하는 과정이 반복되기 때문인데요,

[8,7,6,5,4,3,2,1]이 있다고 치면, [8,7,6,5]와 [4,3,2,1]을 탐색해도 8번 봅니다.

(방금 예시는 정확하게 8번은 아니지만, 모든 데이터가 깔끔하게 정렬되어있지는 않습니다.)

 

그렇다면 아래로 몇 단계까지 내려가는지를 알면 시간 복잡도가 나오는데요,

 N > N/2 > N/4 > N/8 ......1

총 log2 N번 반복하면 1이 됩니다.

 

따라서 시간 복잡도는 O(Nlog2N)이 됩니다.

 

** 관련 문제

https://leetcode.com/problems/sort-an-array/

 

Sort an Array - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

반응형

'백엔드 > 알고리즘, 자료구조' 카테고리의 다른 글

이진 탐색  (0) 2022.02.04
힙 소트  (0) 2022.02.02
퀵 소트  (0) 2022.01.31
트리  (0) 2022.01.30
BFS  (0) 2022.01.30