투 포인터
투 포인터는 배열이나 리스트가 주어졌을 때 탐색의 시간 복잡도를 줄일 수 있습니다.
투 포인터
투 포인터는 배열과 리스트가 주어졌을 때 탐색의 시간 복잡도를 줄이는 목적의 알고리즘이다.
구간, 연속된, 두 수, 세 수 등의 키워드가 보인다면 투 포인터를 떠올려보자.
정렬되어 있다면 투 포인터일 확률이 더 높다.
투 포인터의 설명
주어진 원소의 수가 10,000,000과 같이 너무나 크다고 가정하자.
이럴 때 O(n^2)의 시간 복잡도를 내는 연산은 시간 초과가 된다.
구간을 유지하면서 줄이거나 늘릴 수는 없을까? 라는 생각에서 출발한다.
두 개의 포인터
투 포인터의 이름과 같이 두 개의 포인터를 사용한다.
하나는 구간의 시작, 하나는 구간의 끝을 가리키는 포인터다.
이 두 개의 포인터가 가리키는 구간 내부에서 문제의 조건이 주어진다.
1
2
3
4
5
6
1 2 3 4 5
↑ ↑
S E
S = 시작 포인터
E = 종료 포인터
포인터의 이동
포인터의 이동은 구간의 끝을 가리키는 포인터가 배열의 끝이나 주어진 수에 도달했을 때 종료된다.
예를 들어, 15를 만드는 연속된 수 구간을 찾는다고 가정하자.
구간의 끝을 가리키는 포인터가 15를 넘어간다면 불필요한 탐색이 발생한다.
따라서 여기서 포인터의 이동은 끝을 가리키는 포인터가 15를 가리키면 종료된다.
또한 포인터는 다음의 조건을 만족할 때 이동한다.
- 시작 포인터: 비교 조건보다 현재 조건이 큰 경우
- 종료 포인터: 비교 조건보다 현재 조건이 작은 경우
시작 포인터의 이동은 수를 제외하는 것이고, 종료 포인터의 이동은 수를 추가하는 것이다.
투 포인터의 예시
연속된 자연수의 구간 중 합이 15가 되는 구간의 개수를 구한다고 해보자. 대충 생각나는 조합은 다음과 같다.
1
2
3
4
※ 1 + 2 + 3 + 4 + 5
※ 4 + 5 + 6
※ 7 + 8
※ 15
먼저 포인터의 이동 조건을 결정한다.
- 시작 포인터: 구간의 합이 15보다 클 경우
- 종료 포인터: 구간의 합이 15보다 작을 경우
이를 토대로 코드를 작성한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
while(end_index != 15)
{
if(sum == 15)
{
count++;
end_index++;
sum += end_index;
}
else if(sum > 15)
{
sum -= start_index;
start_index++;
}
else
{
end_index++;
sum += end_index;
}
}
이 기사는 저작권자의
CC BY 4.0
라이센스를 따릅니다.
