[Gold IV] 부분합 - 1806
성능 요약
메모리: 25712 KB, 시간: 308 ms
분류
누적 합(prefix_sum), 두 포인터(two_pointer)
문제 설명
10,000 이하의 자연수로 이루어진 길이 N짜리 수열이 주어진다. 이 수열에서 연속된 수들의 부분합 중에 그 합이 S 이상이 되는 것 중, 가장 짧은 것의 길이를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N (10 ≤ N < 100,000)과 S (0 < S ≤ 100,000,000)가 주어진다. 둘째 줄에는 수열이 주어진다. 수열의 각 원소는 공백으로 구분되어져 있으며, 10,000이하의 자연수이다.
출력
첫째 줄에 구하고자 하는 최소의 길이를 출력한다. 만일 그러한 합을 만드는 것이 불가능하다면 0을 출력하면 된다.
풀이
투 포인터로 풀면 된다. 배열에서 효율적으로 부분적인 합 또는 경우를 구할 경우 dfs같은 전체 반복이 아니라 오른쪽으로 진행하면서 경우의 수를 따지면 된다.
왼쪽과 오른쪽 두 개의 포인터를 두고 오른쪽 포인터를 -> 진행하면서 경우에 벗어나는 경우 왼쪽 포인터를 -> 옮기면서 진행한다.
투포인터 부분합의 핵심적인 부분이다.
int left = 0, right = 0, sum = 0, min = Integer.MAX_VALUE;
//왼쪽, 오른쪽 포인터와 왼쪽과 오른쪽 포인터 사이의 부분합이 조건을 만족하는지 구분할 총 합, 길이의 최소값을 담을 min
//매 시행마다 1.왼오 사이 부분합이 조건에 벗어나는가? 그럼 왼쪽을 당긴다.
2.만약 왼쪽을 다 당겨봤는데도 오른쪽 포인터가 끝에 닿았으면 조건을 만족할 부분합의 경우의 수가 없으므로 종료.
3. 기본적으로 오른쪽을 최대한 늘리면서 조건을 최대한 만족하는 곳 까지 땡긴다.
4. 매 시행의 마지막에는 부분합이 조건과 일치하는지 체크
while (true) {
if (sum >= S) {
sum -= arr[left++];
} else if (right == N) {
break;
}else{
sum += arr[right++];
}
if (sum >= S) {
min = Math.min(min, right - left);(최소 길이를 구해야 하기 때문에 오른쪽과 왼쪽 차)
}
}
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import static java.util.Arrays.stream;
class Main {
static int N, S;
static int[] arr;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
N = Integer.parseInt(input[0]);
S = Integer.parseInt(input[1]);
arr = stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int left = 0, right = 0, sum = 0, min = Integer.MAX_VALUE;
while (true) {
if (sum >= S) {
sum -= arr[left++];
} else if (right == N) {
break;
}else{
sum += arr[right++];
}
if (sum >= S) {
min = Math.min(min, right - left);
}
}
System.out.println(min == Integer.MAX_VALUE ? 0 : min);
}
}
'JAVA 알고리즘 > 유형 문제' 카테고리의 다른 글
[백준 2143 java 자바]두 배열의 합 - 투포인터(부분합, 이중배열) (1) | 2022.10.23 |
---|---|
[백준 1644 java 자바]소수의 연속합 - 투포인터(부분합 효율성) (0) | 2022.10.18 |
[백준 2048 java 자바]2048 - DFS,구현 (0) | 2022.10.09 |
[백준 1062 java 자바]가르침 - 백트래킹,DFS (0) | 2022.10.02 |
[백준 2580 java 자바]스도쿠- 백트래킹,DFS (2) | 2022.09.20 |