본문 바로가기
반응형

분류 전체보기313

깊이 우선 탐색(Depth First Search) : DFS 그래프의 모든 정점들을 방문하는 방법은 크게 두 가지가 있다. 이번에 배워볼 알고리즘은 그중 하나인 깊이 우선 탐색(Depth First Search)이다. 줄여서 흔히 DFS라고 부른다. 이 알고리즘은 깊이 우선 탐색이란 말 그대로 깊이(Depth)를 우선순위로 두고 탐색을 하겠다는 의미이다. ​깊이 우선 탐색은 스택(Stack)을 이용해서 구현한다. 또한, 컴퓨터는 구조적으로 함수를 호출할 때 스택의 원리를 이용하기 때문에 스택을 선언하여 사용하지 않고 재귀적 함수 호출로 구현할 수도 있다. 필자는 재귀적인 구현이 훨씬 간단하고 직관적이기 때문에 보통 재귀적으로 구현을 많이 하는 편이다. 다만, 과도한 재귀 함수 호출은 스택에 함수가 계속 쌓이게 되면서 메모리에 많은 부담을 주기 때문에 이런 경우는 .. 2021. 7. 2.
Lower_bound & Upper_bound 이전에 배운 이분 탐색(Binary Search)은 리스트 내에 찾고자 하는 Key 값이 있을 때만 위치를 반환하고 만약 Key 값이 존재하지 않는다면 아무것도 반환을 하지 않았다. 또한, Key 값이 중복된 경우 정확히 우리가 원하는 Key의 위치를 얻을 수가 없었다. 따라서 Key 값이 존재하지 않더라도 Key에 가장 가까운 원소의 위치를 찾아야 하거나, 중복된 Key 값의 범위, 중복 값을 활용하는 등의 문제를 해결하기 위해선 이분 탐색은 한계가 있다. 이를 위해 이분 탐색을 응용한 두 개의 알고리즘이 존재한다. 당연한 말이지만 이분 탐색을 응용하는 알고리즘이기 때문에 리스트는 정렬이 되어있어야 한다. ​ 첫 번째는 Lower_bound라는 알고리즘이다. Lower_bound는 하한선이라는 뜻으로 .. 2021. 7. 2.
이분 탐색(Binary Search) 데이터가 담긴 리스트를 탐색하는 방법은 크게 순차 탐색(Linear Search)과 이분 탐색(Binary Search)이 존재한다. 예를 들어 { 8, 3, 1, 5, 4, 7, 9, 2, 6, 10}, 10개의 데이터가 담긴 리스트가 있다고 하자. 이 리스트에서 9의 위치를 찾기 위해서는 어떻게 해야 할까? 위 리스트처럼 정렬되지 않은 리스트에서 데이터를 탐색하기 위해서는 어쩔 수 없이 처음부터 끝까지 순차적으로 탐색을 진행하여 9의 위치를 찾는 방법밖에 없을 것이다. ​그렇다면 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}처럼 정렬된 리스트가 있다고 생각해 보자. 이 리스트에서도 9의 위치를 찾기 위해서는 어떻게 해야 할까? 단순하게는 앞서 언급한 방법처럼 처음부터 순차적으로 9의 인덱스.. 2021. 7. 2.
[프로그래머스] 불량 사용자 https://programmers.co.kr/learn/courses/30/lessons/64064 코딩테스트 연습 - 불량 사용자 개발팀 내에서 이벤트 개발을 담당하고 있는 "무지"는 최근 진행된 카카오이모티콘 이벤트에 비정상적인 방법으로 당첨을 시도한 응모자들을 발견하였습니다. 이런 응모자들을 따로 모아 불량 programmers.co.kr [ 문제풀이 ] 모든 banned_id에 대해서 가능한 user_id를 구해준 후 중복을 제외하고 만들 수 있는 조합의 개수를 구해주면 된다. import java.util.*; class Solution { List[] list; Set set; Set ans; int answer, ul, bl; public int solution(String[] user_i.. 2021. 7. 1.
백준 2239 : 스도쿠 https://www.acmicpc.net/problem/2239 2239번: 스도쿠 스도쿠는 매우 간단한 숫자 퍼즐이다. 9×9 크기의 보드가 있을 때, 각 행과 각 열, 그리고 9개의 3×3 크기의 보드에 1부터 9까지의 숫자가 중복 없이 나타나도록 보드를 채우면 된다. 예를 들어 다 www.acmicpc.net [ 문제풀이 ] 전형적인 백트래킹을 활용한 완전 탐색 문제이다. 모든 보드를 차례대로 탐색하여 1~9까지의 수를 채워나가면서 스도쿠 퍼즐이 완성될 수 있는지를 확인해주면 된다. import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReade.. 2021. 7. 1.
기수 정렬(Radix Sort) 이번에 배워볼 정렬 알고리즘은 기수 정렬(Radix Sort)이다. 지금까지 배워온 정렬들은 모두 데이터들을 비교하여 정렬하는 방식이었다. 기수 정렬은 이와는 다르게 데이터를 비교하지 않고 정렬하는 조금 특수한 정렬 알고리즘이다. 기수 정렬은 O(dn)의 시간 복잡도를 가질 정도로 매우 빠른 정렬 알고리즘이다. 여기서 d는 데이터의 자릿수이다. ​ 기수 정렬은 아쉽게도 추가적인 메모리를 필요로 하며, 정렬할 수 있는 데이터 타입이 제한된다는 단점이 있다. 기수 정렬을 사용하기 위해선 데이터의 값들이 동일한 길이를 가지는 숫자나 문자열로 구성되어 있어야 한다. ​그렇다면 0~99 사이의 숫자들로 이루어진 배열을 정렬하는 과정을 살펴보자. 간단하게 100개의 배열을 생성하여 각 인덱스에 저장하여 출력하는 방.. 2021. 7. 1.
힙 정렬(Heap Sort) 이번에 배워볼 정렬 알고리즘은 힙 정렬(Heap Sort)이다. 이전에 우선순위 큐를 공부할 때 힙 자료구조에 대해서 공부하였다. 힙 자료구조는 우선순위 큐를 완전 이진 트리로 구현하는 방법으로 삽입, 삭제 연산이 O(logN)이라는 빠른 시간에 가능하기 때문에 최대, 최소 등 자신이 원하는 조건에 맞는 데이터를 정렬을 유지한 상태로 빠르게 뽑아낼 수 있는 훌륭한 자료구조였다. 힙의 특성을 활용하여 원하는 기준의 원소부터 차례대로 추출하는 방법을 힙 정렬이라 한다. 예를들어 오름차순으로 데이터를 정렬하려고 한다면 최소 힙을 구현하고 원소들을 아무렇게나 차례대로 삽입한 다음, 루트 노드(최솟값)를 데이터 개수만큼 삭제를 통해 뽑아내서 나열하면 원소들이 오름차순으로 정렬된 것을 확인할 수 있다. ​ 힙 정렬.. 2021. 7. 1.
퀵 정렬(Quick Sort) 이번에 배워볼 정렬 알고리즘은 퀵 정렬(Quick Sort)이다. 퀵 정렬은 평균적으로 매우 빠른 수행 속도를 자랑하는 정렬 방법이다. 퀵 정렬도 앞서 배운 합병 정렬처럼 분할 정복(Divide and Conquer) 방법에 근거한다. 하지만 합병 정렬은 항상 리스트를 절반으로 균등하게 나누는 반면에, 퀵 정렬은 피벗(Pivot)이라는 것을 사용하여 비균등하게 분할한다. 피벗을 기준으로 좌측에는 크기가 작은 요소, 우측에는 크기가 큰 요소들을 옮기면서 분할한다. Mid를 기준으로 좌, 우측으로 분할하는 합병 정렬과 조금 차이가 있다. 피벗을 기준으로 분할된 상태에서 피벗을 제외한 좌측, 우측 요소들을 정렬하면 정렬된 리스트를 얻게 된다. 그럼 퀵 정렬은 분할된 상태에서 어떤 방법으로 리스트를 정렬할까? .. 2021. 7. 1.
합병 정렬(Merge Sort) 이번에 배워볼 정렬 알고리즘은 합병 정렬(Merge Sort)이다. 이전까지 배운 정렬들은 최악의 경우 시간 복잡도가 O(N^2)이지만, 합병 정렬은 이와 다르게 최선, 평균, 최악 모든 경우가 O(N logN)의 시간 복잡도를 가지는 빠른 정렬 알고리즘이다. 합병 정렬은 하나의 리스트를 두 개의 균등한 크기로 분할하고 분할된 부분 리스트를 정렬한 다음, 두 개의 정렬된 부분 리스트를 합하여 전체가 정렬된 리스트가 되게 하는 방법이다. 합병 정렬은 분할 정복(Divide and Conquer) 방법에 바탕을 두고 있다. 분할 정복 방법은 문제를 작은 2개의 문제로 분리하고 각각을 해결한 다음, 결과를 모아서 원래의 문제를 해결하는 전략이다. ​ 합병 정렬은 다음의 단계들로 이루어진다. 분할(Divide).. 2021. 7. 1.
반응형