코드스테이츠 - 3회차 백엔드 부트캠프/Section 2
2022.09.27 화 - 의사코드, 시간 복잡도, 탐욕 알고리즘
곰돌이볼
2022. 9. 27. 09:47
📄 학습내용
알고리즘(Algorithm)
- 알고리즘 : 문제를 해결하는 최선의 결과을 구하는 것
- 단계
- 문제 이해하기
문제의 설명, 입출력, 제한 사항, 주의 사항 등 숙지하기 - 전략 세우기
문제 해결에 적합한 알고리즘 선택하기
의사코드 작성하기 - 코드 작성하기
- 문제 이해하기
의사코드(pseudo code)
- 의사코드 : 일상적인 언어로 코드의 동작이나 논리를 작성하는 것
- 의사코드를 구체적으로 작성해야하는 이유 : 코드 작성 시 실행에 문제 없이 동작 가능
- 장점
- 시간 단축
- 디버깅 용이
- 프로그래밍 언어를 모르는 사람과 소통 가능
- 좋은 의사코드 특징
- 자신만의 원칙 세우기
- 일관성
- 다른 사람이 이해 가능해야 함
- 작성방법
- 자연어
- 자연어 + 프로그래밍 언어
시간 복잡도(time complexity)
- 시간 복잡도 : 입력값(N)에 따른 연산 횟수
- 프로그램의 성능을 판단하는 지표로 사용
- 표현 방법
- 빅오 표기법(Big-O) : 가장 최악의 연산 횟수를 고려한 표기 방법
- 프로그래밍을 할 때에는 최악의 경우도 고려해야 하기 때문에 시간 복잡도에서 주로 사용하는 표현 방법
- 빅오메가 표기법(Big-Ω) : 가장 최소의 연산 횟수를 고려한 표기 방법
- 빅세타 표기법(Big-θ) : 최소와 최악의 평균적인 연산 횟수를 고려한 표기 방법
- 빅오 표기법(Big-O) : 가장 최악의 연산 횟수를 고려한 표기 방법
- 빅오 표기법
- O(1) : 입력값과 상관 없이 연산 횟수가 일정(constant complexity)
- O(n) : 입력값에 따라서 연산 횟수가 비례적으로 증가(linear complexity)
- O(log n) : BST와 같은 로직의 시간 복잡도(logarithmic complexity)
- O(n2) : 입력값의 제곱수로 연산 횟수의 비율이 증가(qudratic complexity)
- O(2n) : 2의 배수 형태로 연산 횟수가 증가(exponential complextiy)
탐욕 알고리즘(Greedy)
- 탐욕 알고리즘 : 매순간마다 최적의 해답 선택을 통해서 최종적으로 문제를 해결하는 알고리즘 방식
- 항상 최적의 해답을 도출하지 않음, but 최적과 근사한 값을 빠르게 도출
- 단계
- 선택 절차(Selection Procedure) : 매순간 최적의 해답 선택
- 적절성 검사(Feasibility Check) : 선택한 해답이 문제의 조건과 일치하는지 검사
- 해답 검사(Solution Check) : 해답이 최종 문제를 해결되면 종료, 아니면 1번 과정부터 반복
- 탐욕 알고리즘 적용 조건
- 탐욕적 선택 속성(Greedy Choice Property) : 이전 상황의 선택이 이후 상황에 영향 X
- 최적 부분 구조(Optimal Substructure) : 문제를 작은 문제로 나누어 해결하는 방식을 통해서 최종적으로 문제 해결하는 방식
완전 탐색 알고리즘(Brute-Force Alogrithm)
- 완전 탐색 알고리즘(Brute-Force Algorithm) : 모든 경우의 수를 확인해서 문제를 해결하는 방식(시행착오 방법론)
- 시간ㆍ공간 복잡도를 고려하지 않고 최악의 경우를 통해서라도 문제를 해결하려고 함
- 문제의 복잡도 ↑ ∝ (시간 복잡도, 자원) ↑
- 사용하는 경우
- 사용할 수 있는 적절한 알고리즘이 없는 경우
- 모든 경우의 해답을 확인해야 하는 경우
- 사용되는 알고리즘
- 순차 검색 알고리즘(sequential search) : 배열에서 특정 값 검색
- 문열 매칭 알고리즘(brute-force string matching) : 길이가 N인 문자열에서 길이가 M인 문자열의 포함 여부 탐색
- 선택 정렬 알고리즘(selection sort)
- 버블 정렬 알고리즘(bubble sort)
- tree 자료구조의 완전 탐색 알고리즘(DFS, BFS)
- 동적 프로그랭(DP, Dynamic Programming)
이진 탐색 알고리즘(Binary Search Alogrithm)
- 이진 탐색 알고리즘(Binary Search Algorithm) : 정렬된 데이터에서 절반씩 나누어서 분할 정복기법으로 탐색하는 알고리즘
- 한계
- 배열을 통해서만 구현 가능
- 배열을 정렬해야 이진 탐색 알고리즘 적용 가능
- 동작 단계
- 시간 복잡도 : O(log N)
- 사용되는 경우
- 사전에서 단어 검색
- 도서관에서 도서 검색
- 대규모 시스템의 리소스 사용 현황 파악
- 반도체 테스트 프로그램의 디지털 & 아날로그 레벨 측정
구현(implement)
- 구현 : 생각한 로직을 코드로 작성하는 것
- 구현 능력 검증 방법
- 완전 탐색(brute force) : 모든 경우의 수를 확인해서 문제를 해결하는 방법
- 시뮬레이션(simulation) : 문제의 복잡한 요구 사항을 코드(과정, 조건)로 구현해서 나온 결과를 확인하는 방법
🧶 발생한 문제 및 해결방법
- 문제점) Ingeter 배열 역순
- 해결방법) Integer 배열을 리스트로 변환해서 Collections.reverse() 메서드 이용
// Integer[] 배열
Integer[] arr = { 1, 2, 3 };
List<Integer> list = Arrays.asList(arr); // 배열(int X) → List
Collections.reverse(list); // Collections.reverse() 메서드를 이용해서 역순으로 만들기
Integer[] reverseArr = list.toArray(arr); // List → 배열
- 문제점) int 배열 오름차순 정렬
- 해결방법) stream 이용 또는 Arrays.sort() 메서드 사용
int[] arr = { 1, 2, 3 };
// 스트림으로 오름차순 정렬
int[] sortArr = Arrays.stream(arr) // IntStream
.sorted() // 오름차순 정렬
.toArray(); // int[]
// Arrays.sort() 메서드 사용
Arrays.sort(arr);
- 문제점) int 배열 내림차순 정렬
- 해결방법) int 배열을 Integer 배열로 변환 후 Arrays.sort() 메서드 이용해서 내림차순 정렬, 정렬 후 Integer 배열을 int 배열로 변환
// 내림차순으로 정렬
int[] arr = { 1, 2, 3 };
Integer[] IntegerArr = // int 배열을 Interger 배열로 변환
Arrays.stream(arr) // IntStream
.boxed() // Stream<Integer>
.toArray(Integer[]::new); // Interger[]
Arrays.sort(IntegerArr, Comparator.reverseOrder()); // 내림차순으로 정렬
int[] reverseArr = Arrays.stream(IntegerArr) // Stream<Integer>
.mapToInt(i -> i) // IntStream
.toArray(); // int[]
- 문제점) int 배열을 Integer 배열로 변환/Integer 배열을 int 배열로 변환
- 해결방법)
// int[] → Integer[]
int[] arr = { 1, 2, 3 };
Integer[] IntegerArr =
Arrays.stream(arr) // IntStream
.boxed() // Stream<Integer>
.toArray(Integer[]::new); // Interger[]
// Integer[] → int[]
arr = Arrays.stream(IntegerArr) // Stream<Integer>
.mapToInt(i -> i) // IntStream
.toArray(); // int[]
⭐ 공부 난이도
탐욕 알고리즘, 시간 복잡도 ☆☆☆☆★
🌕 느낀점
코테 준비할 때, 탐욕 알고리즘을 이용해서 문제를 해결하는 것이 어려웠던 것으로 기억된다. 오늘은 구현을 안하고 이론만 공부해서 그런지 큰 어려움은 존재하지 않았다. 시간 복잡도와 이외의 여러 가지 알고리즘을 복습할 수 있어서 좋았다. 안 좋은 버릇인 생각없이 그냥 유어클래스의 글을 읽고 있었다. 머리를 쓰지 않고 공부하는 것을 유의해야겠다. 공부를 할 떄 이해를 하면서 외우도록 의식할 수 있도록 노력해야겠다.