PS/Problems
[Java] 백준 1806번 부분합 - 투 포인터
CalicoCat22
2022. 2. 6. 21:00
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());
}
}
}