목록컴퓨터과학 (42)
넘치게 채우기
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bIYPD9/btsrBPE8h2X/jzDKFCCBgg24Xe5b0Rv1G0/img.png)
최소 신장 트리 (Minimum Spanning Tree, MST) 신장 트리는 그래프의 모든 정점을 연결하는 트리를 말한다. (사이클이 생기지 않음) 최소 신장 트리는 그래프의 모든 정점을 연결하는 간선들의 가중치의 합이 최소인 트리를 말한다. (신장 트리중 가장 저렴한 비용) 크루스칼 알고리즘(Kruscal's Algorithm) 크루스칼 알고리즘은 최소 신장 트리를 찾는 방법 중 하나이다. 1. 모든 간선들을 가중치 기준으로 오름차순 정렬한다. 2. 가장 작은 가중치의 간선부터 선택한다. 3. 고른 간선이 사이클을 형성한다면, 선택하지 않는다. 4. 2와3을 계속 반복한다. 아래는 크루스칼 알고리즘의 예시이다. 우선, 간선들의 가중치를 기준으로 오름차순 정렬해준다. A-B : 1 A-C : 2 B-..
투 포인터 말 그대로 두개의 포인터를 사용하는 알고리즘이다. (left, right), (start, end)처럼 주로 이름을 붙인다. 슬라이딩 윈도우 투 포인터와 비슷하나, 두 포인터간의 간격이 일정하다.
백트래킹 기법은 해를 찾는 도중, 해가 될 가능성이 없으면 이전으로 되돌아가면서 시간을 아끼는 방법이다. 보통 구현 방식은 DFS의 중간에 조건식을 넣어서, 더 깊게 들어가봤자 의미가 없다는 것을 판단시킨 후, 이전으로 돌아가게 하는 식으로 한다. 이 과정을 가지치기라고 하고, 이 가지치기의 조건을 얼마나 잘 설정하느냐가 관건이 된다.
Brute Force. 무식한 힘이란 뜻인데, 풀어 말하면 무식하게 풀기라고 할 수 있다. 완전히 모든 경우를 탐색하여 조건에 맞는 결과를 가져오는 것이다. 속도가 어떻게 될지라도, 반드시 결과를 가져온다. 선형 구조에서는 주로 순차 탐색, 비선형 구조에서는 BFS와 DFS등을 주로 사용한다. 장점으로는 반드시 답을 찾는다는 점이고, 단점으로는 느리거나 메모리를 많이 사용할 수 있다는 점이다. 브루트 포스의 문제 해결 과정 1. 주어진 문제를 구조화 한다. 2. 구조화 된 문제의 모든 해를 구하도록 탐색한다. 3. 구성된 해를 정리한다.
"당장 최선의 수를 고려하기" 탐욕 알고리즘은 매 선택마다 당장의 최선의 선택을 하여 답에 도달하는 방법이다. 항상 최선의 결과를 보여주지는 않지만 특정 상황들 속에서는 굉장히 효과적이고, 직관적이다. 대표적인 예시로는, 거스름돈이 있다. #include #include using namespace std; int input; int wons[4] = {500, 100, 50, 10}; vector calc_coin(int money) { vector coins = vector(4); coins[0] = money / 500; coins[1] = (money % 500) / 100; coins[2] = (money % 100) / 50; coins[3] = (money % 50) / 10; return ..
"이미 알고있는 답은 또 구하지 않는다" 사실 전혀 다이나믹하지 않고, 프로그래밍이라고 하기에도 애매하다. 벨만이라는 수학자가 펀딩을 잘 받기 위해서, 눈에 띄는 이름을 지은 것이다. 이광근 교수님의 저서 "컴퓨터과학이 여는 세계"에서는 '기억하며 풀기'라는 이름이 쓰였다. 하나의 큰 문제를 작은 문제로 나누어서, 그 결과를 얻고, 큰 문제의 답을 구하는 방식이다. "분할 정복법"과도 유사하다. 다이나믹 프로그래밍에는 두 가지 방법이 있다: 종류 메모이제이션 타뷸레이션 과정 하향식(Top down) 상향식(Bottom up) 구현 재귀 함수 반복문 장점 직관적이다 시간을 더 아낄 수도 있다 단점 재귀함수의 호출이 잦아 느려질 수 있다. DP테이블을 잘 채워야 한다. 기타 Lazy - Evaluation ..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/c6wcvR/btsbDESWAxh/kudlEDXOyvMNZGKa0Ri2N0/img.png)
정렬은 데이터들을 주어진 조건에 맞게 순차적으로 나열하는 것이다. 1. 버블 정렬(Bubble Sort) 한 번 순회할 때마다 마지막 하나가 정렬 된다. 거품이 올라오는 것 처럼 보여서 버블 정렬이라고 한다. 두 수를 비교하여, 조건에 맞으면 자리를 바꾼다. O(N^2)의 시간복잡도를 가진다. def bubble_sort(arr): for i in range(len(arr)): for j in range(len(arr)): if arr[i] < arr[j]: arr[i], arr[j] = arr[j], arr[i] 2. 선택 정렬(Selection Sort) 테이블에서 가장 작은 노드를 찾아서 맨 앞으로 위치를 바꾼다. 맨 앞에 놓인 노드 뒤부터 다시 똑같은 과정을 반복한다.(가장 작은 노드를 0번째 인..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/lYMD8/btsaXm5CVZQ/YXkmSUvKMPM4yURsndMb21/img.png)
BFS BFS(Breadth First Search)는 너비 우선 탐색으로, 가까운 노드부터 탐색하는 알고리즘이다. BFS에서는 큐 자료구조를 이용하여 구현한다. 인접한 노드들 중 방문하지 않은 노드를 큐에 추가하면 가까운 노드부터 탐색하는 것이다. 동작 방식은 다음과 같다: 1. 탐색 시작 노드를 큐에 넣고, 방문처리한다. 2. 큐에서 노드를 꺼내 큐의 인접 노드들 중 방문하지 않은 모든 노드들을 큐에 삽입하고, 순서대로 방문처리한다. 3. 2번의 과정을 계속해서 반복한다. 노드 '1'부터 시작해서 '1'을 큐에 넣고 방문처리한다. 노드 '1'을 큐에서 꺼내고, '1'의 인접 노드들 중 방문하지 않은 노드들을 모두 큐에 넣고 방문처리한다. 노드 '2'를 큐에서 꺼내고, 2에 인접한 노드들 중 방문하지 ..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bY9Cif/btsaV269Pel/VBzPU6wmAyaIuG191G1nq0/img.png)
DFS DFS는 Depth-Fisrst Search. 깊이 우선 탐색이다. 그래프에서 깊은 부분을 우선적으로 탐색하는 알고리즘이다. 스택 자료구조를 사용하고, 최대한 깊숙히 노드를 방문하고, 끝에 도달하면 다시 돌아가서 다른 경로를 탐색한다. DFS 는 다음의 동작과정이 있다: 1. 탐색 시작 노드를 스택에 삽입하고, 노드를 방문처리한다. 2. 스택 맨 위에 있는 노드에서 방문하지 않은 인접 노드가 있으면, 그 인접 노드를 스택에 넣고, 방문처리한다. 방문하지 않은 인접 노드가 없으면, 스택에서 최상단 노드를 꺼낸다. 3. 2번을 계속 방문한다.(스택이 빌 때까지) DFS의 과정 1부터 탐색을 시작한다. 1을 스택에 넣고, 방문처리를 한다. '1'에서 방문하지 않은 인접 노드 '2', '3', '4'가 ..
재귀 함수란 자기 자신을 다시 호출하는 함수를 의미한다. 자기 자신을 계속해서 호출하다가, 일정한 조건이 만족되면 함수를 반환하여 결과를 도출한다. 컴퓨터 내에서 재귀 함수는 스택 자료구조와 동일하다. 함수를 계속 호출했을 때, 마지막으로 호출된 함수가 먼저 종료되어야 첫 함수가 종료된다. 아래는 재귀 함수의 대표적인 예시인 팩토리얼이다. def factorial(n): if n == 0 or n == 1: return 1 else: return n * factorial(n-1) 재귀 함수의 장점은 수학의 점화식을 표현한 코드여서 매우 간결한 표현이 가능하단 것이다. 단, 끝없이 재귀 함수가 반복되지 않도록 함수를 끝낼 수 있도록 조건을 만들어놓아야 한다.