🧫 문제 분석
✔️ 출처
📖 문제

누적합 문제를 한번도 안풀어봐서 기본 개념을 익히고 풀어봤다.
여기서는 투 포인터 알고리즘을 사용한다.
시작 포인터 : start
끝 포인터 : end
처음 start 와 end를 첫번째 요소 위치에 둔다.
end를 움직일때마다 해당 end에 값을 sum에 더하고
그 값이 목푯값 s 이상인지 확인한다. <= 중요.. 이걸 제대로 안봐서 삽질했다.
sum >= s 이면 end - start 와 기존 count 중 더 작은 값을 취한다.
🔅 문제 풀이
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int s = Integer.parseInt(st.nextToken());
int start = 1, end = 1;
int sum = 0;
int count = n;
int[] arr = new int[n + 1];
st = new StringTokenizer(br.readLine());
for (int i = 1; i <= n; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
boolean flag = false;
while (true) {
if (end >= arr.length && sum < s) {
break;
}
if (sum < s) {
sum += arr[end++];
} else {
count = Math.min((end - start), count);
sum -= arr[start++];
flag = true;
}
}
if (flag) {
System.out.println(count);
} else {
System.out.println(0);
}
}
}
sum >= s 인데 sum - arr[start] , start++ 하는 이유
우선 sum이 목푯값 s에 도달하면 이 길이가 최댓값이 된다.
예를 들어
N : 4 S : 5
1 2 3 4
라고 하자
필자의 코드대로면
start : 1
end : 4 (end++ 후위 연산자 때문에)
길이 : 3 , sum = 6이다
여기서 end 를 증가시키고 더해버리면
길이가 4가 되어 현재 부분합의 최소 길이를 넘어가버린다.
따라서 sum이 목푯값 sum 이 되면
이 부분합의 길이를 최댓값으로 잡고
sum - arr[start++] 를 하여서 목푯값을 만족하는 더 짧은 길이를 찾는다.
리팩토링
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int s = Integer.parseInt(st.nextToken());
int[] arr = new int[n + 1];
int start = 1, end = 1; // 1번 부터 시작
int sum = 0;
int count = n + 1;
st = new StringTokenizer(br.readLine());
for (int i = 1; i <= n; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
while (end < arr.length || sum >= s) {
if (sum < s) {
sum += arr[end++];
} else {
count = Math.min((end - start), count);
sum -= arr[start++];
}
}
System.out.println((count == n + 1) ? 0 : count);
}
}
여러사람들의 코드를 보면서 내 코드를 더 단순하게 바꿔보았다.
❗ 오답노트 / 필요한 지식
- 누적합이자 투 포인터에 대한 공부를 하게 되었으므로 잘 기억해두고 익히자
- start, end를 0으로 할 경우 while문에서 end <= n 으로 바꾸면 된다.
'baekjoon' 카테고리의 다른 글
백준 1004번 : 어린 왕자 자바 (1) | 2024.08.27 |
---|---|
백준 2252번 : 줄 세우기 자바 (0) | 2024.08.14 |
백준 1074번 : Z 자바 (0) | 2024.07.30 |
백준 16918번 : 봄버맨 자바 (1) | 2024.07.03 |
백준 2751 자바 (0) | 2023.11.03 |