11003번 최솟값 찾기 (Java)
Date: Updated:카테고리: baekjoon
문제 설명
N개의 수 A1, A2, …, AN과 L이 주어진다.
Di = Ai-L+1 ~ Ai 중의 최솟값이라고 할 때, D에 저장된 수를 출력하는 프로그램을 작성하시오. 이때, i ≤ 0 인 Ai는 무시하고 D를 구해야 한다.
제한 조건
- 시간제한 : 2.4초 (java 11은 2.6초)
- 메모리제한 : 512MB
입력 설명
첫째 줄에 N과 L이 주어진다. (1 ≤ L ≤ N ≤ 5,000,000)
둘째 줄에는 N개의 수 Ai가 주어진다. (-109 ≤ Ai ≤ 109)
출력 설명
첫째 줄에 Di를 공백으로 구분하여 순서대로 출력한다.
예제 입력 및 출력 1
12 3
1 5 2 3 6 2 3 7 3 5 2 6
1 1 1 2 2 2 2 2 3 3 2 2
나의 풀이
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
import java.util.LinkedList;
import java.util.Deque;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int numLength = Integer.parseInt(st.nextToken());
int L = Integer.parseInt(st.nextToken());
st = new StringTokenizer(br.readLine());
Deque<Node> deque = new LinkedList<>();
for(int i=0; i<numLength; i++){
int currentValue = Integer.parseInt(st.nextToken());
// 덱의 마지막 값이 새로운 값보다 크면 삭제 (오름차순 정렬 역할)
while(!deque.isEmpty() && deque.getLast().value > currentValue){
deque.removeLast();
}
deque.addLast(new Node(currentValue, i));
// 인덱스 범위에서 벗어난 값 제거
if(deque.getFirst().index <= i - L) deque.removeFirst();
bw.write(deque.getFirst().value+" ");
}
br.close();
bw.flush();
bw.close();
}
static class Node {
int value;
int index;
Node(int value, int index){
this.value = value;
this.index = index;
}
}
}
새로운 값과 Deque의 last값 비교를 통해 Deque의 first에 최소값이 오도록 유지한다.
이때 first의 인덱스가 정해진 범위를 벗어나면 제거한다. (슬라이딩 윈도우)
양방향 큐 구조인 Deque를 활용하여 제한된 범위(Ai-L+1 ~ Ai) 내에서 슬라이딩 윈도우 알고리즘을 적용하면 풀 수 있다.
댓글남기기