© 2025 anveloper.dev
GitHub·LinkedIn·Contact

목차

  • 문제
  • 입력
  • 출력
  • 예제
  • 풀이
  • 코드
  • 복잡도
풀이 목록으로 돌아가기

BOJ 1806 - 부분합

2023-06-30
BOJ
골드 IV
java
원본 문제 보기
누적 합
두 포인터

문제

BOJ 1806 - 부분합

N개의 수로 이루어진 수열에서 합이 S 이상인 연속 부분 수열 중 가장 짧은 것의 길이를 구하라.

입력

첫째 줄에 N과 S, 둘째 줄에 N개의 수가 주어진다.

출력

최소 길이를 출력한다. 합이 S 이상인 부분 수열이 없으면 0을 출력한다.

예제

입력출력
10 15 5 1 3 5 10 7 4 9 2 82

풀이

투 포인터로 윈도우 합이 S 이상일 때 왼쪽을 줄이며 최소 길이를 갱신한다.

  1. R 포인터를 오른쪽으로 이동하며 합에 더한다
  2. 합이 M 이상이면 최소 길이를 갱신하고 L 포인터를 이동하며 합에서 뺀다
  3. R이 끝에 도달할 때까지 반복한다

핵심 아이디어: 양수 수열에서 투 포인터는 각 포인터가 최대 N번 이동하므로 O(N)에 최소 길이 부분합을 찾는다.

코드

package day649;
 
import java.util.*;
import java.io.*;
 
public class Day617BOJ1806부분합 {
  public static void main(String[] args) throws Exception {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer st = new StringTokenizer(br.readLine());
    int ans = 987654321;
    int N = Integer.parseInt(st.nextToken());
    int M = Integer.parseInt(st.nextToken());
    int[] arr = new int[N];
    st = new StringTokenizer(br.readLine());
    for (int i = 0; i < N; i++)
      arr[i] = Integer.parseInt(st.nextToken());
    int L = 0;
    int R = 0;
    int slide = 0;
    while (true) {
      if (slide < M) {
        if (R == N)
          break;
        slide += arr[R++];
      } else {
        ans = Math.min(ans, R - L);
        slide -= arr[L++];
      }
    }
    System.out.println(ans == 987654321 ? 0 : ans);
  }
}

복잡도

  • 시간: O(N)
  • 공간: O(N)