문제
어떠한 자연수 N은, 몇 개의 연속된 자연수의 합으로 나타낼 수 있다.
당신은 어떤 자연수 N(1 ≤ N ≤ 10,000,000)에 대해서, 이 N을 몇 개의 연속된 자연수의 합으로 나타내는 가지수를 알고 싶어한다.
이때, 사용하는 자연수는 N이하여야 한다.
예를 들어, 15를 나타내는 방법은
15,
7+8,
4+5+6,
1+2+3+4+5
의 4가지가 있다. 반면에 10을 나타내는 방법은
10,
1+2+3+4
의 2가지가 있다.
N을 입력받아 가지수를 출력하는 프로그램을 작성하시오.
시간제한 : 2초
자연수 N의 최대 크기가 천만이기 때문에, O(nlogn)의 복잡도를 가지는 알고리즘도 N이 천만일 때 약 2억3천 번의 연산이 필요하기 때문에 위험해 보인다.
따라서 O(n)의 시간복잡도를 가지는 방식으로 해결해야 한다.
그렇기 때문에 투 포인터 알고리즘을 사용하여 해결했다.
투포인터 알고리즘은 특정한 합을 가지는 연속된 수열들을 O(n)의 복잡도로 탐색 할 수 있다.
투포인터 알고리즘
start와 end 와 같은 이름으로 포인트 이름을 설정
초기에는 start = end = 0으로 시작하며
대소 관계는
start <= end 에 해당한다
2개의 포인터는 계산할 부분 배열의 시작과 끝을 가르킨다.
이 방식을 통해 특정한 합을 가지는 연속 수열을 찾을 수 있다.
1. start와 end를 0으로 둔다.
2. sum의 초기값은 end와 start가 같은 자리에 있으므로 그 자리에 해당하는 값이다.
3. 구하고자 하는 합의 특정 값을 target으로 지정하고
4. sum < target 이라면 end를 1 증가시키고. sum에 end의 값을 더한다.
5. sum > target 이라면 sum에서 start자리의 값을 빼고. end를 1 증가시킨다.
6. sum == target 이라면 count 또는 수열을 저장한다. 수열이라면 (end와 start만으로 수열을 구할 수 있으니) 그러나 수열 저장 과정은 O(n) 이므로 O(n^2) 의 시간 복잡도를 갖게 될 수 있다.
7. 해당하는 방식으로 start = end가 될때까지 진행한다. 또는 count를 1로 두고 (N 그자체의 합은 항상 경우의수가 동일하므로) end 가 N이 될때까지 진행한다.
N칸의 1차원 배열이 있을 때, 부분 배열 중 그 원소의 합이 target이 되는 경우의 수는 구간합을 구간 배열로 O(1)으로 구한다 해도 부분배열이 가능한 모든 원소 조합을 고려하는 방식이기 때문에 N * (N + 1) / 2 이므로 시간복잡도는 O(n^2) 이다.
그러나 투포인터 알고리즘을 활용하면 O(n) 을 가질 수있다.
해답
class Solution {
public void solve() throws IOException {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int count = 1;
int start_index = 1;
int end_index = 1;
int sum = 1;
while (end_index!=N){
if (sum == N) {
count++;
end_index++;
sum = sum + end_index;
}
else if(sum < N){
end_index ++;
sum = sum + end_index;
}
else if(sum > N) {
sum = sum - start_index;
start_index++;
}
}
System.out.println(count);
}
}
이 풀이에서는 연속된 수열이 아닌 그저 자연수 15의 연속된 수의 합 개수를 구하는 것이기 때문에 배열을 사용할 필요 없이
start와 end의 계산 만으로 합의 수를 구할 수 있었다.
또한 주어진 수 N 그 자체가 target이므로 count에 1을 초기화 해둔 상태로 end가 N이 될때까지만 반복하도록 하여
반복 횟수를 줄였다.
입력값은 N 하나이므로 BufferedReader 말고 scanner를 사용했다.
'알고리즘 > java' 카테고리의 다른 글
[stack] 백준 1874 스택수열 (0) | 2024.07.31 |
---|---|
[슬라이딩 윈도우] 백준 12891 Dna 비밀번호 (0) | 2024.07.29 |
[투포인터] 백준 1940 주몽 (0) | 2024.07.27 |
[백준] 구간 합 4 (0) | 2024.07.23 |