본문 바로가기

알고리즘37

[Algorithm] 다익스트라 (Dijkstra) 다익스트라(Dijkstra) 알고리즘 다익스트라 알고리즘은 다이나믹 프로그래밍을 활용한 대표적인 최단 경로 탐색 알고리즘이다. 인공위성 GPS 소프트웨어 등에서 가장 많이 사용되는 알고리즘이다. 다익스트라 알고리즘은 특정한 하나의 정점에서 다른 모든 정점으로 가는 최단 경로를 계산한다. 이때, 거리가 음수인 간선은 포함할 수 없다. 하지만, 현실 세계에서는 거리가 음수인 경로는 존재하지 않아서 다익스트라는 현실 세계에 적용하기 매우 적합한 알고리즘 중 하나이다. 기본적으로 그리디 알고리즘을 바탕으로 하고 있다. 거리를 기록하며 이미 최단 경로를 구한 곳은 다시 구할 필요가 없기 때문에 다이나믹 프로그래밍으로 보기도 한다. 항상 최단 경로를 찾고 탐욕적으로 선택한다. - 그리디 이미 계산된 경로를 저장후,.. 2023. 3. 13.
[Algorithm] 동적 계획법 (DP. Dynamic Programming) 동적 계획법 (DP. Dynamic Programming) 동적 계획법이란 하나의 복잡한 문제를 여러 개의 간단한 하위 문제로 나누어 푼 다음, 이를 결합하여 답을 도출해내는 방법이다. 나누어진 하위 문제들의 결과를 따로 저장해두었다가 이후 동일한 문제가 나왔을 시 저장해둔 결과를 가져다가 쓰면 같은 문제를 반복해서 풀지 않아도 되기 때문에 문제를 해결하는데 시간을 절약할 수 있다. 즉 한번 푼 하위 문제는 중복해서 풀지 않는다. 그렇다면 어떤 문제인 경우에 동적 계획법으로 해결할 수 있을까? 우선 문제를 나누어봤을 때 반복되는 작은 문제들이 나와야 되고, 전체 문제의 최적해가 부분 문제의 최적해들로 구성되는지 확인해야 된다. 이 두 가지 조건 모두 충족한다면 동적 계획법으로 풀 수 있는 문제다. 동적 .. 2023. 3. 13.
[Algorithm] 최소 공통 조상 (LCA. Lowest Common Ancestor) 최소 공통 조상 (LCA. Lowest Common Ancestor) → 두 정점이 만나는 최초 부모 정점을 찾는 것 트리 형식이 아래와 같이 주어졌다고 하자 4와 5의 LCA는? → 4와 5의 첫 부모 정점은 '2' 4와 6의 LCA는? → 첫 부모 정점은 root인 '1' 찾는 법 해당 정점의 depth와 parent를 저장해두는 방식이다. 현재 그림에서의 depth는 아래와 같을 것이다. [depth : 정점] 0 → 1(root 정점) 1 → 2, 3 2 → 4, 5, 6, 7 parent는 정점마다 가지는 부모 정점을 저장해둔다. 위의 예시에서 저장된 parent 배열은 아래와 같다. // 1 ~ 7번 정점 (root는 부모가 없기 때문에 0) const parent[] = {0, 1, 1, 2.. 2023. 3. 13.
[Algorithm] 최장 증가 수열 (LIS. Longest Increasing Sequence) LIS (Longest Increasing Sebsequence) 최장 증가수열 문제는 어떤 배열에서 특정 부분을 지워 만들 수 있는 증가 부분수열 중 가장 긴 수열을 구하는 문제다. 배열이 [1, 4, 4, 6, 8, 3]이면 증가부분수열은 [1, 4, 6, 8], [4, 6, 8], [4, 8], [6, 8]이다. 여기서 가장 긴 증가 부분수열은 [1, 4, 6, 8]이다.가장 쉬운 방법은 모든 증가부분수열을 구해 가장 긴 것을 찾는 것이지만, 같은 연산을 반복하기 때문에 O(2^n)의 시간복잡도를 가진다. 이 문제를 효율적으로 해결하는 두 가지 방법이 있다. Ex) 배열 (1, 5, 4, 2, 3, 8, 6, 7, 9, 3, 4, 5) 에서 부분 수열 (1, 2, 3, 6, 7, 9) 는 전체 수열.. 2023. 3. 13.
[Algorithm] 선형 탐색, 분할 정복, 이진 탐색(Binary Search) 선형 탐색, 순차 탐색 (Linear Search, Sequential Search) 정렬된 배열 안에서 특정 원소를 찾기 위해 인덱스 0부터 차례로 탐색 원소를 건너뛰는 일 없이 순차적으로 탐색 선형 탐색을 이용해 O(n)의 시간복잡도로 구현할 수 있다. const arr = [1, 2, 3, 4, 5, 6]; const linearSearch = (sortedIntArray, value) => { for (let i = 0; i < arr.length; i++){ if (arr[i] === value) return i; } return -1; } console.log(linearSearch(arr, 3)); // 2 console.log(linearSearch(arr, 5)); // 4 console.. 2023. 3. 9.
[Algorithm] 계수 정렬 (Counting Sort) 계수 정렬 (Counting Sort) 계수 정렬은 특정한 조건이 부합될 때만 사용할 수 있지만 데이터 수가 많더라도 중복된 값이 많이 분포돼있는 배열을 정렬할 때, 효과적이고 빠른 정렬 알고리즘이다. 최대, 최소 값 차이가 100만 이하일 경우 효과적이다. 카운팅 정렬이라고 하기도 한다. 선택, 삽입, 퀵 정렬처럼 데이터를 비교하며 위치를 변경하는 비교 기반의 정렬 알고리즘이 아니다. 계수 정렬의 조건 데이터의 크기 범위가 제한된 경우 ex) 0 ~ 100 까지의 점수를 정렬하는 경우 숫자가 클 수록, count를 숫자만큼 만들어야하므로, 메모리 낭비가 심하기 때문이다. 데이터가 양의 정수인 경우 데이터가 실수인 경우 무한의 범위를 가질 수 있으므로 1번 조건에 부합하지 못함 가장 큰 데이터와 가장 작.. 2023. 3. 8.
[Algorithm] 힙 정렬 (Heap Sort) 완전이진트리(complete binary tree) 완전 : 루트(root) 노드부터 시작해 왼쪽, 오른쪽 순으로 자식 노드부터 추가하는 모양 이진 : 부모가 가질수 있는 자식의 개수는 최대 2개 트리 : 요소의 상하 관계를 부모(parent)와 자식(child), 자식 간의 관계를 형제(sibling) 루프 : 트리의 첫 노드 리프 : 트리의 마지막 노드 자료구조 ‘힙(heap)’ 완전 이진 트리의 일종으로 우선순위 큐를 위하여 만들어진 자료구조 최댓값, 최솟값을 쉽게 추출할 수 있는 자료구조 최대 힙 : '부모의 값이 자식의 값보다 항상 큰' 조건을 만족하는 완전이진트리 최소 힙 : '부모의 값이 자식의 값보다 항상 작은' 조건을 만족하는 완전이진트리 자식과 부모 관계식 부모 : a[(i - 1) /.. 2023. 2. 27.
[Algorithm] 병합 정렬 (Merge Sort) 병합 정렬 (Merge Sort) 합병 정렬이라고도 부르며, 이 정렬은 안정 정렬에 속하며, 분할 정복 기법과 재귀 용법을 활용한 정렬 알고리즘이다. * [분할 정복(divide and conquer) 방법] 큰 문제를 작은 문제 단위로 쪼개면서 해결해나가는 방식. 문제를 작은 2개의 문제로 분리하고 각각을 해결한 다음, 결과를 모아서 원래의 문제를 해결하는 전략이다. 분할 정복 방법은 대개 순환 호출을 이용하여 구현한다. 병합 정렬은 정렬할 원소 목록을 원소가 하나 밖에 남지 않을 때까지 절반으로 잘라 비슷한 크기의 두 부분으로 계속 나눈다. 정렬할 때는 각 절반의 가장 작은 요소를 비교하여 수행된다. (각 목록의 첫 번째 요소가 가장 먼저 비교된다.) 더 작은 값으로 시작되는 것을 정렬된 목록에 추가.. 2023. 2. 27.
[Algorithm] 퀵 정렬 (Quick Sort) 퀵 정렬 (Quick Sort) Quick Sort은 분할 정복(divide and conquer) 방법 을 통해 주어진 배열을 정렬한다. * [분할 정복(divide and conquer) 방법] 큰 문제를 작은 문제 단위로 쪼개면서 해결해나가는 방식. 문제를 작은 2개의 문제로 분리하고 각각을 해결한 다음, 결과를 모아서 원래의 문제를 해결하는 전략이다. 분할 정복 방법은 대개 순환 호출을 이용하여 구현한다. Quick Sort은 불안정 정렬에 속하며, 다른 원소와의 비교만으로 정렬을 수행하는 비교 정렬에 속한다. 분할 정복 알고리즘의 하나로, 평균적으로 매우 빠른 수행 속도를 자랑하는 정렬 방법이다. 또한, 합병 정렬(Merge Sort)과 달리 Quick Sort는 배열을 비균등하게 분할한다. 프.. 2023. 2. 27.
[Algorithm] 삽입 정렬 (Insertion Sort) 삽입 정렬 (Insertion Sort) 손 안의 카드를 정렬하는 방법과 유사하다. Insertion Sort는 Selection Sort와 유사하지만, 좀 더 효율적인 정렬 알고리즘이다. Insertion Sort는 2번째 원소부터 시작하여 그 앞(왼쪽)의 원소들과 비교하여 삽입할 위치를 지정한 후, 원소를 뒤로 옮기고 지정된 자리에 자료를 삽입 하여 정렬하는 알고리즘이다. Selection Sort와 Insertion Sort는 k번째 반복 이후, 첫번째 k 요소가 정렬된 순서로 온다는 점에서 유사하다. 하지만, Selection Sort는 k+1번째 요소를 찾기 위해 나머지 모든 요소들을 탐색한다. 하지만 Insertion Sort는 k+1번째 요소를 배치하는 데 필요한 만큼의 요소만 탐색하기 때문.. 2023. 2. 27.