본문 바로가기

PS/Problems

[Java] 백준 1806번 부분합 - 투 포인터

https://www.acmicpc.net/problem/1806

 

1806번: 부분합

첫째 줄에 N (10 ≤ N < 100,000)과 S (0 < S ≤ 100,000,000)가 주어진다. 둘째 줄에는 수열이 주어진다. 수열의 각 원소는 공백으로 구분되어져 있으며, 10,000이하의 자연수이다.

www.acmicpc.net

연속된 수들의 부분합 중 s 이상인 배열의 최소 길이를 찾는 문제이다.

처음에는 생각 없이 펜윅 트리를 써서 바로 시간 초과를 먹고

투 포인터 코드로 새로 짰다.

 

index 0부터 시작하는 left, right 포인터에 대하여

sum이 s이상이라면 left++ 해서 무조건 sum이 줄도록

s 미만이라면 right++ 해서 무조건 sum이 늘어나도록 하였다.

 

시간복잡도는 O(n)?

 

import java.util.*;
import java.io.*;

public class g4_1809 {
    static FastScanner fs = new FastScanner();
    static PrintWriter pw = new PrintWriter(System.out);

    public static void main(String[] args) {
        int n = fs.nextInt(), s = fs.nextInt();
        int[] pp = new int[n];
        for (int i=0;i<n;i++) pp[i] = fs.nextInt();

        int sum = pp[0];
        int left = 0, right = 0, ans = Integer.MAX_VALUE;
        while (left <= right && right < n){
            if (sum >= s){
                ans = Math.min(ans, right - left + 1);
                sum -= pp[left];
                left++;
            }
            else{
                right++;
                if (right != n) sum += pp[right];
            }
        }
        if (ans == Integer.MAX_VALUE) pw.println(0);
        else pw.println(ans);
        pw.close();
    }

    // ----------input function----------

    static void sort(int[] a) {
        ArrayList<Integer> L = new ArrayList<>();
        for (int i : a)
            L.add(i);
        Collections.sort(L);
        for (int i = 0; i < a.length; i++)
            a[i] = L.get(i);
    }

    static class FastScanner {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer("");

        String next() {
            while (!st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        int[] readArray(int n) {
            int[] a = new int[n];
            for (int i = 0; i < n; i++)
                a[i] = nextInt();
            return a;
        }

        long nextLong() {
            return Long.parseLong(next());
        }
    }
}