본문 바로가기

Algorithm & Data Structure17

[자료구조] 스택(Stack) - JAVA(자바) 스택(Stack) 가장 마지막에 넣었던 값이 가장 먼저 나오게 되는 후입선출(LIFO: Last In First Out)이다. 위 스택 그림에서 push(4) 한 뒤, pop()을 하면 top위치에 있는 데이터는 3이 된다. 덱과 달리 한쪽에서만 삽입, 삭제 연산이 실행된다. 삽입,삭제, 읽기 연산의 시간복잡도는 O(1)이고, 탐색은 특정 데이터를 찾을때까지 탐색하므로 O(n)이다. 그래프(Graph)의 깊이 우선 탐색(DFS)시 사용된다. 2가지 구현 방법(배열, 리스트)이 있다. 자바에서는 Stack 클래스를 구현하여 제공하고 있다. (자바에서 스택의 사이즈는 정해져 있지 않다) Stack 생성 예시 Stack stack = new Stack(); Stack 메소드 top - 스택의 최상단 위치 pu.. 2023. 1. 30.
[자료구조] 덱(Deque) - JAVA(자바) 덱(Deque) Double-Ended Queue의 줄임말이다. front에서 삽입, last에서 삭제하는 큐와 달리 front와 last 모두 삽입, 삭제가 가능하다. 덱을 front에서만 삽입,삭제를 하게 하면 스택처럼 사용할 수 있다. 삽입, 삭제 연산의 시간복잡도 O(1)이고, index를 통해 요소에 접근할 수 있기 때문에 탐색시에도 O(1)의 시간복잡도를 가진다. 삽입, 삭제가 빠른 편이다. 크기가 가변적이다. 한쪽으로만 입력이 가능한 덱 - 스크롤(Scroll), 한쪽으로만 삭제가 가능한 덱 - 셸프(shelf) 덱의 중간 원소의 삽입, 삭제가 어렵다. 자바에서 덱은 인터페이스로만 작성되어 있다. Deque 생성 (LinkedList로 구현예시) - 자바에서 Deque은 인터페이스로만 작성되.. 2023. 1. 30.
[알고리즘] 투 포인터(Two Pointer) - JAVA(자바) 투 포인터(Two Pointer) 배열 또는 리스트에서 두개의 포인터의 위치를 기록해가면서 원하는 결과를 찾아내는 알고리즘 (2가지 방법존재) 시작할 때, 정렬된 배열에서 처음 인덱스와 마지막인덱스를 두 개의 포인터가 가리키는 경우 시작할 때, 처음 인덱스를 두 개의 포인터가 모두 가리키는 경우 시간복잡도는 O(n)이다. (부분 배열을 이용해 탐색하기 때문에 O(n)) 보통 선형 공간 탐색시 시간복잡도가 O(n²)이상이 되는 부분을 O(n)으로 줄이기 위해 사용된다. 이를 저격하는 문제는 투 포인터를 사용하지 않으면 시간초과가 발생한다. 두 포인터를 사용한 풀이에 대한 자세한 설명은 아래 글에 작성해두었다. N이 되는 연속된 자연수의 합 - 처음 인덱스를 두 개의 포인터가 모두 가리키는 경우 https:.. 2023. 1. 28.
[알고리즘] 합병정렬(Merge Sort) - JAVA 합병정렬(Merge Sort) 주어진 배열 또는 리스트의 길이가 1이 될 때까지 분할한 뒤, 부분 배열을 정렬하면서 합치는 정렬이다. 배열의 길이가 1이 될 때(하나의 원소만 가진 상태)까지 분할한다. - 분할(divide) 1이 되면 길이가 짧은 것부터 부분배열을 정렬한다. - 정복(conquer) 정렬된 배열끼리 합친다. - 결합(combine) 정복과 결합을 반복하다 부분배열이 1개 남으면 정렬된 전체 배열이 된다. 병합 정렬이라고도 한다. 시간복잡도는 O(nlogn)로 일정하다. 분할이 트리형태(6개의 원소를 가진다면 6->3->1)로 이루어지기 때문에 합치는 과정에서 깊이가 log²n이 되고, 원소의 대소 비교횟수는 합치는 과정마다 원소를 다 보게 되므로 n번이 된다. 따라서 시간복잡도는 O(n.. 2023. 1. 27.
[알고리즘] 삽입정렬(insertion Sort) - JAVA(자바) 삽입정렬(insertion Sort) 2번째 원소부터 n번째까지 그 이전에 있던 원소들과 비교하며 삽입할 위치를 찾아 정렬한다. 2번째부터 차례대로 이전에 있던 원소들과 비교한다. 비교할 때, 이전에 있던 원소보다 작다면 서로 위치를 바꾼다. 크다면 앞은 정렬된 배열로 더이상 비교가 필요없기 때문에 다음 번째 원소로 넘어간다. 이 과정을 n번째 원소까지 반복하며 정렬한다. 시간복잡도는 O(n²)이 걸린다. 정렬할 때마다 이전에 정렬된 배열과 위치를 찾는 원소를 비교한다. 하지만 모두 정렬되어있는 경우(최선의 경우)에는 한번만 비교하면 되므로 O(n)의 시간복잡도를 가진다. 제자리 정렬(=입력받은 배열외에 다른 메모리가 필요하지 않은 정렬) 안정 정렬(=동일한 값에 대해서는 순서가 바뀌지않는다.) 배열 [.. 2023. 1. 25.
[알고리즘] 선택정렬(Selection Sort) - Java(자바) 선택정렬(Selection Sort) 원소를 넣을 위치를 이미 정하고, 그 위치에 최솟값을 찾아서 넣는 정렬 방법이다. 첫번째 위치에는 배열의 모든 원소를 비교한 뒤, 최솟값을 그자리에 넣는다. 두번째 위치에는 첫번째 자리를 제외한 모든 원소를 비교한 뒤, 최솟값을 그자리에 넣는다. 이과정을 반복하며 정렬한다. 시간복잡도는 O(n²)이 걸리며 효율적이지 않다. 정렬할 때마다 남은 모든 원소를 봐야한다. -> n개라면 첫번째자리 n-1번, 두번째 자리는 n-2번이 반복된다. 제자리 정렬(=입력받은 배열외에 다른 메모리가 필요하지 않은 정렬) 불안정 정렬(=동일한 값에 대해서도 순서가 변경된다.) 구현 방법은 단순해서 쉬운 편이다. 배열 [6,3,4,1,5,2]이 있을 때, 선택정렬로 정렬하는 과정 [구현 .. 2023. 1. 24.
[알고리즘] 카운팅 정렬(Counting Sort) - JAVA(자바) 백준 2108번 통계학, 10989번 수 정렬하기3를 풀 때, 카운팅 정렬을 사용했었다. 카운팅 정렬에 대해 정리해두고자 글을 작성한다. 카운팅 정렬(Counting Sort) 계수 정렬이라고도 한다. 데이터의 크기 비교가 아닌 등장횟수를 통해 정렬하는 방법 시간복잡도가 O(n)으로 성능이 매우 좋은 알고리즘이다. (빠른 정렬 알고리즘은 대부분 O(nlogn)으로 카운팅 정렬이 훨씬 빠름) 최대 범위가 작을 때 유리하다. (정렬할 배열의 최댓값+1 길이의 배열 생성 필수 -> 최대 범위가 커지면 메모리 사용량증가) 먼저 정렬할 배열, 카운팅 배열, 정렬 후 배열을 생성한다. int[] arr = {1,1,1,5,5,2,2,2,7,8,4,4,4,4,9}; //정렬할 배열 int[] counting_arr .. 2023. 1. 16.