본문 바로가기

알고리즘/분류

(22)
구간 트리 솔루션 [1. 개요] 구간 트리란? 보통 일차원 배열을 대상으로 특정 구간에 대한 쿼리를 O(logn) 에 할 수 있다. 구간 트리를 대상으로 하는 연산은 크게 3가지로 아래와 같다. 1. init() 2. query() 3. update() 구간 트리 존재 의의 특정 구간의 합은 부분합으로 더 빠르게 O(1) 만에 구할 수 있지만, 어떤 원소의 값이 바뀌면 O(n) 의 시간을 들여 부분 합을 다시 만들어야 한다. 구간 트리는 O(logn) 으로 update 하고, 구간의 합을 O(logn) 으로 구할 수 있다. 구간 트리 구현을 아래와 같이 한가지 패턴으로 작성하도록 한다. u # 구간 트리의 노드 번호, (Root 의 노드 번호는 1 이다.) left # u 의 포함되는 구간의 가장 왼쪽 right # u ..
우선 순위 큐 관련 솔루션 [1. 개요] 우선 순위 큐(=편의 상 힙으로 표기) 는 정렬 상 우선순위가 높은 원소를 먼저 꺼낼 수 있는 큐이다. 최대 힙 최소 힙 힙을 대상으로 하는 push 와 pop 모두 O(logn) 으로 동작한다. 힙 내부 데이터 변경으로 인해 heapify 가 필요할 수도 있지만, 이런 경우에 자주 없다. 다익스트라에서 특정 노드에 대한 가중치가 바뀌는 경우가 대표적이지만, 이 때에는 힙에 다시 푸쉬하는 편이 더 간단하다. heapify 는 보통 O(n) 으로 동작하여 다소 느려, 오히려 더 안 좋을 수 있다(?). 보통의 문제는 크게 최대 힙, 최소 힙 둘 중 하나만 사용하는 경우가 다수이지만, 두 가지 힙 모두 사용하여 풀어야 하는 문제도 간혹 존재한다. 대표적으로 Running median 같은 문제..
이진 검색 트리 솔루션 [1. 개요] 자료 구조 구현 이진 트리는 그 특성 상 배열을 이용하여 구현한다. index 0 은 사용하지 않고, index 1 을 루트로 사용한다. leaf node 는 왼쪽 노드가 maxNode 보다 큰 경우이다. => 왼쪽 노드가 없으면 오른쪽 노드도 당연히 없다. => 보통 노드 개수가 문제에 주어진다. (완전 이진 트리가 아닌 이상, 마지막 노드 id 를 유추 할 수 없으므로?) 완전 이진 트리 모든 레벨에 노드가 가득찬 이진 트리이다. 트리의 깊이가 K 일 때, 노드의 개수가 2K-1 개를 갖는다. maxNode id 는 2^k 이다. => k == 2, 트리에 존재 할 수 있는 노드 id 는 1, 2, 3 => maxNode == 4 각 레벨 별 노드 id 범위를 쉽게 구할 수 있다. =>..
트리 관련 문제 솔루션 [1. 개요] Tree 자료 구조의 특징 하나의 노드는 여러개의 자식을 가질 수 있어도, 부모는 하나만 가질 수 있다. 루트에서 어떤 노드로 가는 경로는 유일하다. => 부모가 반드시 하나만 있다는 점을 생각해보자. => leaf 에서 위로 올라가는 경로는 유일하다. Root 는 트리에서 딱 하나 존재한다. Leaf 는 자식이 없는 노드이다. Cycle 이 존재하지 않는 연결그래프 (무방향) 이다. => 어떤 그래프에서 DFS 를 한번 수행하면, DFS 스패닝 트리가 된다. => 어떤 그래프에서 BFS 를 한번 수행하면, 역시 트리가 된다. => 이러한 점을 고려하도록 한다. Tree 의 지름 재귀적인 성질을 갖는다. => 재귀적인 방식으로 코드를 작성해야 하는 이유이다. => 전위, 중위, 후위 순회...
큐 관련 문제 솔루션 [1. 개요] [2. 예제] https://testkernelv2.tistory.com/467 https://testkernelv2.tistory.com/426 https://testkernelv2.tistory.com/415 => queue 를 교차하여 사용하지 않고, (이 방법은 다소 시간이 걸림) => 세그먼트 트리를 이용해서 풀 수 있다. d e f
스택 관련 문제 솔루션 [1. 개요] fd [2. 예제] https://testkernelv2.tistory.com/539 https://testkernelv2.tistory.com/540 c d e f
부분 합 솔루션 [1. 개요]공식pSum[i] = A[i] - pSum[i-1]구간 [a, b] 의 원소들의 합sum[a~b] = pSum[b] - pSum[a-1]a-1 의 원소의 접근해야 할 필요가 있으므로,구현의 편의 성을 위해 배열은 0이 아닌 1부터 시작하도록 하는 것이 좋다.이러한 개념은 2차원 배열로도 확장 된다. 2차원 배열 상에서 부분 합이 살짝 까다로울 수 있다.단순 넓이 개념으로 생각하면 아래와 같이 구할 수 있다. pSum[y,x] 를 [0,0] ~ [y,x] 내 속한 원소의 합으로 생각하는 것이다.link 463 예체 참조, [2. 예제]https://testkernelv2.tistory.com/463https://testkernelv2.tistory.com/534https://testkernel..
이분탐색 솔루션 [1. 개요] 보통 매우 큰 범위를 갖는 어떤 값 중 최적 값을 찾을 때 유용하다. N 이 [0, 1,000,000,000] 사이의 값일 때, 어떤 식을 최대 혹은 최소로 만드는 N 을 구한다. 완전 탐색 시, 시간 초과가 당연하다. 그러나 이 범위에서 이분 탐색을 하면, 32번 이내로 찾을 수 있다. => 어떤 조건을 만족하는 최대 N 을 구해야 할 때 => 먼저 중간 값을 찾고, 이 값을 주어진 식에 대입 => 특정 조건을 만족하면 상위 구간에서 이분 탐색 진행 => 만족하지 않으면 하위 구간에서 이분 탐색 진행 주의 할점 범위와 반복문 조건이 중요하다. (구간 및, 반복문 조건 (등호 유무) 등이 다르면 틀린다.) => 구간은 보통 [a, b], 폐구간 이어야 한다. => 그래서 반복문 조건은 wh..
탐욕법 솔루션 [1. 개요] 완전 탐색, 동적 계획법과 같이 전체 문제를 여러 개의 부분 문제로 나누고, 각 부분 문제를 해결하는 것 까지는 같으나, 각 단계마다 지금 당장 좋은 방법만을 선택한다는 것에서 다르다. 즉, 현재 선택이 앞으로 남은 선택들에 어떤 영향을 끼칠지는 고려하지 않는다. 탐욕법을 사용하는 경우 탐욕법을 사용해도 항상 최적해를 구할 수 있는 경우 => 이때는 완전 탐색, 동적 계획법 등으로 풀 수 없는 경우라고 볼 수 있다. => 보통 완전탐색, 동적 계획법으로 구현 시 제한 시간 이내로 풀 수 없는 경우. => 약간의 직관력이 필요하다. 탐욕 알고리즘에 대한 증명은 보통 일정한 패턴을 갖는다. 탐욕적 선택 속성 => 탐욕적 선택을 해서 손해 볼 일은 없다. => 귀류법을 사용하여 증명 최적 부분 ..
동적계획법 솔루션 [1. 개요] 일반적인 접근 방식 완전 탐색에서 시작한다. => 완전 탐색 코드를 먼저 작성 => 중복되는 문제에 대한 메모이제이션을 적용. 보통 중복되는 부분문제들을 최초 한번만 계산하고, 나머지는 이 값을 재활용 한다. => 메모이제이션 => 최초 캐시 메모리는 -1 로 초기화 한다. (아직 이 부분 문제가 계산되지 않음을 의미한다.) => 캐시 메모리는 문제에서 주어진 공간 복잡도를 만족해야 한다. 메모이제이션 할 대상을 선정해야 한다. => 보통 캐시의 index 로 사용 함. => 부분 문제의 입력으로 주어지는 패턴을 갖는다. => 문제 입력의 범위를 보고 눈치껏 메모이제이션 할 대상을 선정해야 한다. => 특히, 캐시를 다차원 배열로 해야하는 경우 최적화 문제 => 여러개의 가능한 답 중 가장..