console.log

[BOJ] 1806 부분합 JAVA 본문

알고리즘/백준

[BOJ] 1806 부분합 JAVA

foresight 2023. 11. 4. 08:28

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

 

1806번: 부분합

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

www.acmicpc.net

 

메모리 : 22,464kb
실행시간 : 236ms

 

문제분석

투 포인터

N^2 만 해도 시간초과
--> N 또는 logN 정도로 줄여야 함
--> 투 포인터

 

걸린시간

1시간 ⏱️

 

풀이방법

1. 입력 받으면서 누적합 저장
2. 투 포인터 (시작점, 끝점) 지정
3-1. 현재 범위 (시작점 ~ 끝점)의 누적합이 S보다 크거나 같을 경우 : 최소 길이 갱신, 시작점 한칸 옮기기
3-2. S보다 작을 경우 : 끝점 한칸 옮기기

 

포인트

시간초과 때문에 최대 N만에 끝내야함
투 포인터 쓰면 2N이라서 가능

 

코드

package study.day1020;

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

public class BOJ_1806_부분합 {		// 메모리 : 22,464 kb		실행시간 : 236 ms
	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 S = Integer.parseInt(st.nextToken());

		int[] arr = new int[N + 1];
		int len = Integer.MAX_VALUE;
		st = new StringTokenizer(br.readLine());
		for (int i = 1; i <= N; i++) {
			arr[i] = arr[i - 1] + Integer.parseInt(st.nextToken());

		}

		int left = 0;
		int right = 1;
		while(right <= N) {
			if(arr[right] - arr[left] >= S) {
				len = Math.min(len, right - left);
				left++;
			} else {
				right++;
			}
		}

		System.out.println(len == Integer.MAX_VALUE ? 0 : len);
	}
}

'알고리즘 > 백준' 카테고리의 다른 글

[BOJ] 12919 A와 B 2 JAVA  (0) 2023.11.07
[BOJ] 4485 녹색 옷 입은 애가 젤다지? JAVA  (1) 2023.10.29
[BOJ] 13549 숨바꼭질 3 JAVA  (0) 2023.10.26
[BOJ] 1238 파티 JAVA  (0) 2023.10.24
[BOJ] 1342 행운의 문자열 JAVA  (1) 2023.10.04