PS

[백준] 1806번 : 부분합[Java]

devkdh 2025. 7. 18. 04:15

#풀이

이진탐색 풀이

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[] nums = new int[N];
        st = new StringTokenizer(br.readLine());
        for(int i = 0; i<N; i++){
            nums[i] = Integer.parseInt(st.nextToken());
        }
        int left = 1;
        int right = N;
        int ans = 0;
        while(left<=right){
            boolean flag = false;
            int mid = (left+right)/2;
            int sum = 0;
            for(int i = 0; i<mid; i++ ){
                sum+=nums[i]; // 초기 세팅
            }
            if(sum>=S){
                right = mid-1;
                ans = mid;
                continue;
            }
            for(int i = 1; i<N-mid+1; i++ ){
                sum-=nums[i-1];
                sum+=nums[i+mid-1];
                if(sum>=S){
                    flag = true;
                    right = mid-1;
                    ans = mid;
                    break;
                }
            }
            if(!flag)left = mid+1;

        }

        System.out.println(ans);
    }

}

투 포인터 풀이

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[] nums = new int[N];
        st = new StringTokenizer(br.readLine());
        for(int i = 0; i<N; i++){
            nums[i] = Integer.parseInt(st.nextToken());
        }
        int left = 0;
        int right = 0;
        int ans = Integer.MAX_VALUE;
        int sum = 0;
        while(true){
            if(sum>=S){
                sum-=nums[left];
                ans = Math.min(ans,right-left);
                left++;
            }
            else if (right == N)         
                break;
            else{
                sum+=nums[right++];
            }
        }
        if(ans==Integer.MAX_VALUE)ans = 0;
        System.out.println(ans);
    }

}

#성능

이분탐색

 

투포인터

#정리

이 문제는 두가지 방법으로 풀 수 있다.

1. 이분탐색+슬라이딩 윈도우 -> 이분탐색으로 최소길이를 찾는다. 해당 길이에서 S보다 큰 부분합이 있는지 슬라이딩 윈도우로 확인한다. 이 경우 시간복잡도는 O(NlogN)이다.

2. 투 포인터로 모든 부분 합에 대해 S와 비교한다. 이 경우 시간복잡도는 O(N)이다.