투 포인터(Two Pointer) 알고리즘 : 리스트에 순차적으로 접근해야 할 때 2개의 점의 위치를 기록하면서 처리
투 포인터는 다음 2가지 케이스가 대표적인 문제 유형이다.
1. 특정한 합(M)을 가지는 부분 연속 수열 찾기
- 시간복잡도 : O(N) { O(2*N)}
- 동작과정
1) 시작점(s)와 끝점(e)를 첫 번째 원소의 인덱스(0)로 지정한다
2) s부터 e까지 현재 부분합이 특정한 합(M)과 같다면 카운트한다.
3) s부터 e까지 현재 부분합이 특정한 합(M)보다 작다면 e를 1 증가시킨다.
4) s부터 e까지 현재 부분합이 특정합 합(M)보다 크다면 s를 1 증가시킨다.
5) 모든 경우를 확인할 떄까지 2)번부터 4)까지의 과정을 반복한다.
#include <iostream>
#include <vector>
using namespace std;
int n = 5, m = 5; // 데이터의 개수 n, 찾고자 하는 부분합 m
int arr[] = {1, 2, 3, 2, 5};
int main(void) {
int cnt = 0;
int interval_sum = 0;
int e = 0;
// start를 차례때로 증가시키며 반복
for (int s = 0; s < n; s++) {
// end를 가능한 만큼 이동시키기
while (interval_sum < m && e < n) {
interval_sum += arr[e++];
}
// 부분합이 m일 때 카운트 증가
if (interval_sum == m) {
cnt++;
}
interval_sum -= arr[s];
}
cout << cnt << endl;
return 0 ;
}
2. 정렬되어 있는 두 리스트의 정렬된 합집합
- 시간복잡도 : O(N+M) [N: a 크기, M: b 크기]
- 동작과정
1) 정렬된 리스트 a와 b를 입력 받는다.
2) 리스트 a에서 처리되지 않은 원소의 인덱스를 i로 지정한다.
3) 리스트 b에서 처리되지 않은 원소의 인덱스를 j로 지정한다.
4) a[i]와 b[j]중 저 작은 원소를 결과(result) 리스트에 담고 해당 리스트의 인덱스(i 또는 j)를 1 증가시킨다.
5) a와 b에 처리할 원소가 없을 때까지 2) ~ 4) 과정을 반복한다.
#include <iostream>
#include <vector>
using namespace std;
// 사전에 정렬된 리스트 a, b 선언
int n = 3, m =4;
vector<int> a = {1, 3, 5};
vector<int> b = {2, 4, 6, 8};
int main(void) {
int i = 0;
int j = 0;
// 리스트 a와 b의 모든 원소 담을 수 있는 결과 리스트
vector<int> result;
// 더 이상 리스트 a와 b에 처리할 원소가 없을 때까지 반복
while (i < n || j < m) {
// 리스트 b의 모든 원소가 처리되었거나, 리스트 a의 원소가 더 작을 경우
if (j >= m || (i < n && a[i] <= b[j])) {
result.push_back(a[i++]);
}
// 처리되지 않은 리스트 b의 원소가 존재하고 리스트 a의 모든 원소가 처리되었거나, 리스트 b의 원소가 더 작을 경우
else {
result.push_back(b[j++]);
}
}
for (int r : result) {
cout << r << " ";
}
cout << endl;
return 0 ;
}
2번 코드에서 while문 안의 if-else구문에 조건이 여러개 들어가는데 이 부분이 익숙하지 않다.
익숙해지도록 하자.
'알고리즘 > Template' 카테고리의 다른 글
[Algorithm][Template] 순열과 조합 (0) | 2022.01.22 |
---|---|
[Algorithm][Template] Prefix Sum, 구간 합 계산 (0) | 2022.01.20 |
[Algorithm][Template] 2차원 리스트 90도 돌리기 (0) | 2022.01.20 |
[Algorithm][Template] 소수의 판별 (0) | 2022.01.20 |
[Algorithm][Template] 위상 정렬(Topology Sort) (0) | 2022.01.15 |