11. 2020 AL林 정기 스터디 11
문제를 하나 읽어봅시다. – 1920번(link)
시간 제한 2초
메모리 제한 128MB
입력 1≤N≤100,000 1≤M≤100,000
모든 정수의 범위는 -231 보다 크거나 같고 231보다 작다.
출력 답이 존재하면 1, 존재하지 않으면 0
12. 프로그래밍 문제 해결
2020 AL林 정기 스터디 12
시간 제한 프로그램이 실행되는 시간의 제한
메모리 제한 프로그램이 사용할 수 있는 메모리의 제한
✓ 프로그래밍 문제 해결
주어진 입력 데이터에 대해서 제한된 시간과 제한된 메모리 내에서 결과를 출력
13. 시간 제한 – 108 룰
2020 AL林 정기 스터디 13
✓ 108 룰
컴퓨터는 1초에 간단한 동작을 약 108번 할 수 있다.
N의 제한과 시간 제한이 주어지면 시간복잡도를 예측할 수 있다.
입력 크기(n)에 따른 연산의 횟수(O(n))
14. 시간 제한 – 108 룰
2020 AL林 정기 스터디 14
한번 해볼까요?
N의 크기 시간 제한 시간 복잡도
8 1초 𝑂 𝑁 , 𝑂 𝑁2
, 𝑂 𝑁3
, 𝑂 2𝑁
, 𝑂(𝑁!)
25 1초 𝑂 𝑁 , 𝑂 𝑁2
, 𝑂 𝑁3
, 𝑂 2𝑁
500 1초 𝑂 𝑁 , 𝑂 𝑁2 , 𝑂 𝑁3
5000 1초 𝑂 𝑁 , 𝑂 𝑁2
1000000 1초 𝑂 𝑁
15. 메모리 제한
2020 AL林 정기 스터디 15
C++에서 정수 자료형 int 하나는 4바이트, long long 하나는 8바이트
방금과 비슷하게 예상 가능하겠죠?
ex) 400MB = 정수(int) 108개가 들어간 배열
일반적으로 문제에서 메모리 제한은 넉넉하게 줘서
메모리 때문에 어려운 경우는 상대적으로 적습니다.
20. 풀이 방법
2020 AL林 정기 스터디 20
N은 최대 100,000
M은 최대 100,000
즉 N*M은 최대 10,000,000,000 (100억) = 약 100초 > 2초
시간 초과
21. 풀이 방법 2
2020 AL林 정기 스터디 21
1. 전역변수로 232크기의 정수 배열 count 생성
2. N개의 A[i]에 대해서 count[A[i] + 231] += 1
3. 다음을 M번 반복
• 수 X에 대해서 만약 count[X + 231]가 0보다 크면 1을 출력
• 아니면 0을 출력
22. 풀이 방법 2
2020 AL林 정기 스터디 22
1. count
2. count
3. 다음을 M번 반복
• 수 X에 대해서 만약 count[X + k]가 0보다 크면 1을 출력
• 아니면 0을 출력
-4+k -3+k -2+k -1+k 0+k 1+k 2+k 3+k 4+k 5+k
0 0 0 0 0 0 0 0 0 0
-4+k -3+k -2+k -1+k 0+k 1+k 2+k 3+k 4+k 5+k
0 0 0 0 0 1 1 1 1 1
, k = 231
23. 풀이 방법 2
2020 AL林 정기 스터디 23
배열에 인덱스로 접근하는 것은 상수시간 (count[index] => O(1))
따라서 시간복잡도는 max(O(N), O(M))
24. 풀이 방법 2
2020 AL林 정기 스터디 24
하지만,
232크기의 정수 배열의 크기는 어떻게 될까요?
4Byte * 232 = (4 * 4 * 1073741824)Byte = 약 17180MB > 128MB
메모리 초과
26. 풀이 방법 3
2020 AL林 정기 스터디 26
1. N개의 수를 배열에 저장
2. 배열을 정렬 => O(NlogN)
3. 다음을 M번 반복
• N개의 배열에서 X가 있는지 이분 탐색한다. => O(logN)
• 있으면 1, 없으면 0을 출력한다.
27. 풀이 방법 3 - 이분탐색?
2020 AL林 정기 스터디 27
N크기의 정렬된 배열에서 특정 값을 찾는 최대 연산 횟수는 log2N
7 is the target value (출처 wikipedia)
탐색할 필요가 없다.
28. 풀이 방법 3
2020 AL林 정기 스터디 28
N은 최대 100,000 / M은 최대 100,000
N개를 정렬 => O(NlogN)
이분탐색을 M번 => O(MlogN)
log(100,000) = 16~17
따라서 O(NlogN) 또는 O(MlogN)는 최대 약 1,700,000 < 2초
맞았습니다
29. 프로그래밍 문제 해결
2020 AL林 정기 스터디 29
✓ 프로그래밍 문제 해결
주어진 입력 데이터에 대해서 제한된 시간과 제한된 메모리 내에서 결과를 출력
자료구조와 알고리즘을 이용해 문제를 효율적으로 해결하는 과정
효율적으로 최적화 하는 과정이 없다면? => 구현 ( 완전탐색, 시뮬레이션 )
31. 완전 탐색
2020 AL林 정기 스터디 31
✓ 브루트 포스(Brute-force search)
✓ 답이 될 수 있는 모든 경우의 수를 탐색한다.
✓ 가장 쉽고 단순한 방법
✓ 더 효율적으로 문제를 풀기 위한 기반(출발점)이 되기도 한다.
32. 완전 탐색
2020 AL林 정기 스터디 32
하지만 완전 탐색만으로도 충분히 어려운 문제도 있다.
→ 짧은 시간 안에 빠르고 정확하게 구현하는 능력이 중요
33. 완전 탐색
2020 AL林 정기 스터디 33
비선형 구조(그래프)에서의 완전 탐색
- BFS(너비 우선 탐색) : 3주차
- DFS(깊이 우선 탐색) : 5주차
34. [BOJ 2309번] 일곱 난쟁이
2020 AL林 정기 스터디 34
9개의 정수 중에서 합이 100이 되는 7개의 정수를 구한다.
→ 9개 중에서 2개를 제외했을 때 나머지 정수의 합이 100
→ 2개를 제외하는 모든 경우의 수는 9C2 = 36가지
→ 36가지 경우를 완전 탐색
37. 전부 구현되어있습니다.
2020 AL林 정기 스터디 37
기본 자료구조는 라이브러리에 구현되어있습니다.
(구조는 간단해보이지만 직접 구현하려고 보면 그렇게 쉽지 않습니다.)
알고리즘 문제를 풀면서 실제 큐, 스택, 덱을 구현할 일은 없습니다.
예외) 삼성 역량 테스트 B형과 C형
38. 동적 배열 / 문자열
2020 AL林 정기 스터디 38
배열(문자열)의 크기를 동적으로 변경할 수 있다.
※ 파이썬은 기본 자료구조가 동적이다.
자료구조 C++ Java Python
동적 배열 vector ArrayList []
문자열 string String ""
39. 동적 배열 / 문자열
2020 AL林 정기 스터디 39
#include 또는 import하고
쓰면 됩니다.
40. 스택
2020 AL林 정기 스터디 40
“Last In First Out”
마지막으로 들어간 데이터가
가장 먼저 나오는 자료구조
stack.top()
stack.push()
stack.pop()
stack.empty()
41. 큐
2020 AL林 정기 스터디 41
먼저 들어간 데이터가
가장 먼저 나오는 자료구조
queue.front()
queue.back()
queue.push()
queue.pop()
queue.empty()
“First In First Out”
42. 덱
2020 AL林 정기 스터디 42
스택과 큐를 합친 구조
양쪽에서 push pop이 가능
push
push
pop
pop
43. 스택 / 큐 / 덱
2020 AL林 정기 스터디 43
push
pop
push pop
push
push
pop
pop
스택
큐
덱