코딩테스트/백준

백준 2003번 : 수들의 합2 [Java]

블로그 주인장 2023. 9. 1.

🎁 문제 링크

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

 

2003번: 수들의 합 2

첫째 줄에 N(1 ≤ N ≤ 10,000), M(1 ≤ M ≤ 300,000,000)이 주어진다. 다음 줄에는 A[1], A[2], …, A[N]이 공백으로 분리되어 주어진다. 각각의 A[x]는 30,000을 넘지 않는 자연수이다.

www.acmicpc.net

🎁 문제 설명

🎁 코드

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        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 start = 0, end = 0, sum = 0, cnt = 0;
        while (true) {
            if (sum >= M) {
                sum -= arr[start++];
            } else if (end == N) {
                break;
            } else {
                sum += arr[end++];
            }

            if (sum == M) {
                cnt++;
            }
        }

        System.out.println(cnt);
    }
}

🎁 풀이

★ i번째 수부터 j번째 수까지의 합(구간 합) 이기 때문에 투 포인터를 사용하기 적합[시간 복잡도 O(n)]

1. start, end 두 개의 포인터를 배열의 첫 번째에 두고 시작한다. (포인터 : int, 인덱스를 가리킨다.)

2. Start  -> End 포인터까지의 합 sum과 M 을 비교하면서 End 포인터가 배열의 끝에 닿을 때까지 반복

3-1. SUM >= M 인 경우, SUM을 줄여야 M에 가까워지므로, S 포인터를 1 증가시킨다.

3-2. End 포인터가 끝 점에 도달했으면, Start 포인터를 1 증가(오른쪽으로 이동)

3-3. SUM < M 인 경우 , SUM을 늘리기 위해 End 포인터를 1 증가시킨다.

3-4. SUM = M 인 경우, 하나 찾았으므로 COUNT + 1 한다.

 

★ 포인터를 증가 시켰을 때

1. S 포인터는 현재 위치의 원소를 SUM에서 제거

2. E 포인터는 현재 위치의 원소를 SUM에서 증가

반응형

댓글