코딩테스트/two pointer
백준 1806 부분합
의현
2025. 1. 17. 14:38
링크 : https://www.acmicpc.net/problem/1806
문제 설명
더보기
문제
10,000 이하의 자연수로 이루어진 길이 N짜리 수열이 주어진다. 이 수열에서 연속된 수들의 부분합 중에 그 합이 S 이상이 되는 것 중, 가장 짧은 것의 길이를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N (10 ≤ N < 100,000)과 S (0 < S ≤ 100,000,000)가 주어진다. 둘째 줄에는 수열이 주어진다. 수열의 각 원소는 공백으로 구분되어져 있으며, 10,000이하의 자연수이다.
출력
첫째 줄에 구하고자 하는 최소의 길이를 출력한다. 만일 그러한 합을 만드는 것이 불가능하다면 0을 출력하면 된다.
문제 풀이
투 포인터 느낌으로 풀이 (i, startIndex)
for 문을 돌면서 sum 을 구하고 startIndex를 활용해 sum의 범위를 줄여 최소 길이를 구하기
const inputs = require("fs")
.readFileSync("/dev/stdin")
.toString()
.trim()
.split("\n");
const [n, s] = inputs[0].split(" ").map(Number);
const arr = inputs[1].split(" ").map(Number);
let startIndex = 0;
let answer = Infinity;
let sum = 0;
for (let i = 0; i < n; i++) {
sum += arr[i];
// startIndex를 줄여가면서 s보다 클 수 있는지 검사
while (sum - arr[startIndex] >= s) {
sum -= arr[startIndex];
startIndex++;
}
// 더 짧은 길이 구하기
if (sum >= s) {
answer = Math.min(answer, i - startIndex + 1);
}
}
console.log(answer === Infinity ? 0 : answer);
결론
누적합에 투 포인터 느낌을 적절히 사용하는 문제