Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 환급챌린지
- nqueen
- 내돈내산
- 시간복잡도
- 파이썬
- 인강
- AIFFEL
- DFS알고리즘
- 시나공정보처리기사
- 패스트캠퍼스
- FastCampus
- package-install
- 자료구조
- Korean-NLP
- 프림알고리즘
- 해쉬테이블
- 알고리즘
- 최단거리알고리즘
- 크루스칼알고리즘
- 연결리스트
- 작심삼개월
- BFS알고리즘
- 퀵정렬
- Ai
- 1주차완료
- 코딩테스트인강
- 트리구조
- 코딩테스트대비
- 코딩테스트
- 백준알고리즘2920번
Archives
- Today
- Total
DevLog
[패스트캠퍼스 :: 코딩테스트 인강] 7주차 ① 동적 계획법, 퀵 정렬, 병합 정렬 본문
알고리즘/기술면접 완전 정복 올인원 패키지 Online
동적 계획법과 분할 정복 - 01. 동적 계획법과 분할 정복
고급 정렬 알고리즘 - 01. 퀵 정렬
고급 정렬 알고리즘 - 02. 병합 정렬
동적 계획법 (Dynamic Programming)과 분할 정복 (Divide and Conquer)
- 동적 계획법 (DP라고 많이 부름)
- 입력 크기가 작은 부분 문제들을 해결한 후, 해당 부분 문제의 해를 활용해서, 보다 큰 크기의 부분 문제를 해결, 최종적으로 전체 문제를 해결하는 알고리즘
- 상향식 접근법으로, 가장 최하위 해답을 구한 후, 이를 저장하고, 해당 결괏값을 이용해서 상위 문제를 풀어가는 방식
- Memoization 기법을 사용함
- Memoization (메모이제이션) 이란: 프로그램 실행 시 이전에 계산한 값을 저장하여, 다시 계산하지 않도록 하여 전체 실행 속도를 빠르게 하는 기술
- 문제를 잘게 쪼갤 때, 부분 문제는 중복되어, 재활용됨
- 예: 피보나치 수열
- 분할 정복
- 문제를 나눌 수 없을 때까지 나누어서 각각을 풀면서 다시 합병하여 문제의 답을 얻는 알고리즘
- 하양식 접근법으로, 상위의 해답을 구하기 위해, 아래로 내려가면서 하위의 해답을 구하는 방식
- 일반적으로 재귀 함수로 구현
- 문제를 잘게 쪼갤 때, 부분 문제는 서로 중복되지 않음
- 예: 병합 정렬, 퀵 정렬 등
- 공통점
- 문제를 잘게 쪼개서, 가장 작은 단위로 분할
- 차이점
- 동적 계획법
- 부분 문제는 중복되어, 상위 문제 해결 시 재활용됨
- Memoization 기법 사용 (부분 문제의 해답을 저장해서 재활용하는 최적화 기법으로 사용)
- 분할 정복
- 부분 문제는 서로 중복되지 않음
- Memoization 기법 사용 안 함
- 동적 계획법
병합 정렬 (merge sort)
- 알고리즘 분석은 쉽지 않음, 이 부분은 참고로만 알아두자.
- 다음을 보고 이해해보자
- 몇 단계 깊이까지 만들어지는지를 depth라고 하고 i로 놓자. 맨 위 단계는 0으로 놓자.
- 다음 그림에서 n/2222는 2단계 깊이라고 해보자.
- 각 단계에 있는 하나의 노드 안의 리스트 길이는 n/2222 가 된다.
- 각 단계에는 2𝑖2i 개의 노드가 있다.
- 따라서, 각 단계는 항상 2𝑖∗𝑛2𝑖=𝑂(𝑛)2i∗n2i=O(n)
- 단계는 항상 𝑙𝑜𝑔2𝑛log2n 개 만큼 만들어짐, 시간 복잡도는 결국 O(log n), 2는 역시 상수이므로 삭제
- 따라서, 단계별 시간 복잡도 O(n) * O(log n) = O(n log n)
- 몇 단계 깊이까지 만들어지는지를 depth라고 하고 i로 놓자. 맨 위 단계는 0으로 놓자.
- 다음을 보고 이해해보자
def merge(left, right):
merged = list()
left_point, right_point = 0, 0
# case1 - left/right 둘다 있을때
while len(left) > left_point and len(right) > right_point:
if left[left_point] > right[right_point]:
merged.append(right[right_point])
right_point += 1
else:
merged.append(left[left_point])
left_point += 1
# case2 - left 데이터가 없을 때
while len(left) > left_point:
merged.append(left[left_point])
left_point += 1
# case3 - right 데이터가 없을 때
while len(right) > right_point:
merged.append(right[right_point])
right_point += 1
return merged
def mergesplit(data):
if len(data) <= 1:
return data
medium = int(len(data) / 2)
left = mergesplit(data[:medium])
right = mergesplit(data[medium:])
return merge(left, right)
퀵 정렬 (quick sort)
- 기준점(pivot이라고 부름)을 정해서, 기준점보다 작은 데이터는 왼쪽(left), 큰 데이터는 오른쪽(right)으로 모으는 함수를 작성함
- 각 왼쪽(left), 오른쪽(right)은 재귀 용법을 사용해서 다시 동일 함수를 호출하여 위 작업을 반복함
- 함수는 왼쪽(left) + 기준점(pivot) + 오른쪽(right)을 리턴함
quicksort 함수 만들기
- 만약 리스트 개수가 한 개이면 해당 리스트 리턴
- 그렇지 않으면, 리스트 맨 앞의 데이터를 기준점(pivot)으로 놓기
- left, right 리스트 변수를 만들고,
- 맨 앞의 데이터를 뺀 나머지 데이터를 기준점과 비교(pivot)
- 기준점보다 작으면 left.append(해당 데이터)
- 기준점보다 크면 right.append(해당 데이터)
- return quicksort(left) + pivot + quicksort(right)로 재귀 호출
def qsort(data):
if len(data) <= 1:
return data
left, right = list(), list()
pivot = data[0]
for index in range(1, len(data)):
if pivot > data[index]:
left.append(data[index])
else:
right.append(data[index])
return qsort(left) + [pivot] + qsort(right)
정렬 알고리즘은 정말 많이 활용되는 부분인 만큼 기억해야 할 부분도 많다.
[패스트캠퍼스 100% 환급 챌린지 미션 중입니다.]
'IT 개발 > Algorithm 알고리즘' 카테고리의 다른 글
[패스트캠퍼스 :: 코딩테스트 인강] 8주차 ① 이진 탐색 (0) | 2021.04.10 |
---|---|
[패스트캠퍼스 :: 코딩테스트 인강] 7주차 ② 병합정렬 (0) | 2021.04.04 |
[패스트캠퍼스 :: 코딩테스트 인강] 6주차 ② 재귀용법 (0) | 2021.03.28 |
[패스트캠퍼스 :: 코딩테스트 인강] 6주차 ① 선택정렬, 삽입정렬 (0) | 2021.03.27 |
[패스트캠퍼스 :: 코딩테스트 인강] 5주차 ② 정렬 / 버블 정렬 (0) | 2021.03.21 |