투 포인터란?
투 포인터(two pointers) 는 배열 위에 두 개의 인덱스(포인터) 를 두고, 둘을
적절히 움직여 \(O(N^2)\)로 보이는 문제를 \(O(N)\)에 푸는 기법입니다.
모든 쌍이나 모든 구간을 일일이 다 보는 대신, 이미 본 정보를 활용해 포인터를
한 방향으로만 전진시켜 중복 작업을 없앱니다.
1. 두 가지 큰 유형
- 같은 방향(슬라이딩): 두 포인터
l,r이 모두 왼쪽에서 오른쪽으로 이동.
"조건을 만족하는 구간"을 찾을 때. - 마주 보는 방향:
l은 왼쪽 끝,r은 오른쪽 끝에서 가운데로 수렴.
정렬된 배열에서 "합이 목표인 쌍" 등을 찾을 때.
문제 모양에 따라 둘 중 하나를 고릅니다.
2. 핵심 아이디어: 포인터를 되돌리지 않는다
투 포인터가 빠른 이유는 각 포인터가 전체 배열을 한 번씩만 지나가기 때문입니다.
\(l\)과 \(r\)이 각각 최대 \(N\)번 전진하므로 전체 \(O(N)\)입니다.
이것이 가능하려면 단조성이 필요합니다 — 예를 들어 "구간을 늘리면 합이
커진다"처럼, 포인터를 한 방향으로만 움직여도 답을 놓치지 않아야 합니다.
3. 예: 합이 목표인 구간 (양수 배열)
"연속한 부분 배열 중 합이 정확히 \(S\)인 것의 개수"를 구합니다.
l, r을 0에서 시작. 현재 구간 합을 들고:
- 합 < S 이면: r을 늘려 구간을 키운다.
- 합 >= S 이면: l을 늘려 구간을 줄인다.
- 합 == S 이면: 센다.
합이 너무 작으면 오른쪽으로 키우고, 너무 크면 왼쪽을 버린다 — 두 포인터가
앞으로만 가며 모든 유효 구간을 정확히 한 번씩 봅니다.
4. 예: 정렬된 배열에서 두 수의 합
정렬된 배열에서 합이 \(T\)인 쌍 찾기. 양 끝에서 시작:
l = 0, r = n-1
- a[l] + a[r] == T : 찾음
- a[l] + a[r] < T : l++ (합을 키워야)
- a[l] + a[r] > T : r-- (합을 줄여야)
정렬되어 있으니 합의 크기에 따라 어느 포인터를 움직일지 명확합니다.
5. 투 포인터 vs 슬라이딩 윈도우
둘은 매우 가깝습니다. 슬라이딩 윈도우는 투 포인터의 한 형태로, 보통 창 안의
정보(합·개수 등)를 유지하며 같은 방향으로 움직이는 경우를 부릅니다. 별도
주제로 더 다룹니다.
정리
투 포인터는 두 인덱스를 한 방향(또는 마주 보며)으로 움직여 \(O(N^2)\)를 \(O(N)\)으로
줄입니다. 핵심은 포인터를 되돌리지 않아도 되는 단조성입니다. "연속 구간",
"정렬된 배열의 쌍"이 보이면 떠올리세요. 다음 강의에서 구현합니다.