어떤 자연수 을 연속된 자연수의 합으로 나타내는 가짓수를 구하는 문제입니다.
이 무려 천만입니다. 만약 모든 구간을 탐색하는 브루트포스나 백트래킹을 사용한다면 100조 번의 연산이 필요하므로 절대 통과할 수 없습니다.
연속된 자연수의 합을 구할 때는 포인터 두 개(start, end)를 사용하여 구간을 조절하는 투 포인터 알고리즘이 최적입니다.
이 방식은 포인터가 각각 한 번씩만 배열 끝까지 이동하므로 의 시간 복잡도로 해결 가능합니다.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
int n = scanner.nextInt();
// start, end 포인터와 현재 합 sum 초기화
int start = 1, end = 1, sum = 1, count = 0;
while (end <= n) {
if (sum == n) {
count++; // 경우의 수 발견
sum -= start++; // start 이동 (구간 축소)
} else if (sum < n) {
sum += ++end; // end 이동 (구간 확장)
} else {
sum -= start++; // sum > n 인 경우, start 이동 (구간 축소)
}
}
System.out.println(count);
}
}
}
투 포인터는 정렬된 배열이나 연속된 수열에서 구간을 다룰 때 강력한 힘을 발휘합니다. 이번 문제는 투 포인터의 가장 표준적인 형태를 보여주는 좋은 예제였습니다.