
예전에 비슷한 문제를 풀었던 것 같아서.. 그렇게 하다가 틀렸습니다 받고 투포인터로 다시 풀었다 ㅎㅎ.. 사실 바로 떠오르긴 했는데 확신이 안서서.. 암튼 풀어봅시다.

처음부터 더한다. 더하다가 S보다 커지면 앞에서 하나씩 뺀다. 그때 count를 비교해서 최소를 저장한다.. 가 되겠다.
public static int twoPointerSubTotal(int[] sequence, int S){
int i = 0, j, min = 100000001;
long sum = 0;
for(j=0;j<sequence.length;j++){
sum += sequence[j];
while(sum >= S){
min = Math.min((j - i + 1), min);
sum -= sequence[i];
i++;
}
}
return (min == 100000001) ? 0 : min;
}
j가 실제로 더하는 인덱스이고, i는 sum >= S 일때 앞에서부터 순차적으로 빼는 역할을 한다. 순차적으로 빼야하니까 while문을 실행하고, sequence[i]를 빼고나면 i를 증가시켜준다.
예외처리가 있다. 이 문제는 S보다 크거나 같은 부분합 중에 개수가 적은걸 출력한다. 딱 같아야 하는게 아니다.
3 5
2 3 10
답 : 1 -> '10 >= 5'이기 때문에..
2 3
1 3
답 : 1 -> '3 >= 3'
3 3
1 1 1
답 : 3
3 5
1 1 1
답 : 0 -> '전체 수열의 합 < S'
반례는 이정도.. 신경쓰면 된다.
전체 수열의 합이 S보다 작은경우를 계산하기 위해 min을 100,000,001 으로 정했다.(최대 S값이 100,000,000 이라서)
아래는 전체 코드이다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class BOJ1806 {
public static int twoPointerSubTotal(int[] sequence, int S){
int i = 0, j, min = 100000001;
long sum = 0;
for(j=0;j<sequence.length;j++){
sum += sequence[j];
while(sum >= S){
min = Math.min((j - i + 1), min);
sum -= sequence[i];
i++;
}
}
return (min == 100000001) ? 0 : min;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N, S, i;
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
S = Integer.parseInt(st.nextToken());
int[] sequence = new int[N];
st = new StringTokenizer(br.readLine());
for(i=0;i<N;i++)
sequence[i] = Integer.parseInt(st.nextToken());
System.out.println(twoPointerSubTotal(sequence, S));
}
}
'코딩가딩가' 카테고리의 다른 글
| [JAVA]BOJ 12891, DNA 비밀번호 (0) | 2024.08.04 |
|---|---|
| [JAVA]BOJ 2230, 수 고르기 (0) | 2024.08.04 |
| [JAVA]BOJ 2110, 공유기 설치 (0) | 2024.08.02 |
| [JAVA]BOJ 6236, 용돈 관리 (0) | 2024.08.02 |
| [JAVA]BOJ 1654, 랜선 자르기 (0) | 2024.08.01 |