1. 문제 설명
2. 접근 방식
0. 사전 세팅
Node Class : 멤버 변수로 index와 value를 가지고 있다. index는 입력에서 해당 값이 나온 순서를 저장하고, value는 실제
값을 저장한다.
NGE 배열 : index에 해당하는 입력 값의 오큰수가 무엇인지 저장한다.
top : stack을 배열로 구현하였기 때문에 top이 어디인지 알려줄 변수로 사용했다.
1. 원리
stack이 비어있으면 현재 조회 중인 입력값을 넣는다.
stack이 비어있지 않은 경우 stack.top과 현재 조회 중인 입력값(A)를 비교한다.
stack.top < A 인 경우
stack.top의 오큰수는 A이므로 NGE 배열의 top의 index에 A를 저장한다.
stack.top의 오큰수는 정해졌음으로 pop하고, 그 다음 top과 A를 또 비교한다.stack.top >= A인 경우
stack.top의 오큰수는 아직 나오지 않았다. 따라서 A를 stack에 push한다.
NGE 배열을 출력하면 각 위치별 오큰수를 구할 수 있다.
- 이때 값이 0인 부분은 입력 전체에서 오큰수가 없는 수이다. 해당 값은 -1로 변환하여 출력한다.
3. 코드 분석
import java.io.*;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int N = Integer.parseInt(br.readLine());
Node [] stack = new Node [N];
int [] NGE = new int [N];
int top = -1;
StringTokenizer st = new StringTokenizer(br.readLine());
stack[++top] = new Node(0, Integer.parseInt(st.nextToken()));
for (int i = 1; i < N; i++) {
Node now = new Node(i, Integer.parseInt(st.nextToken()));
while (top != -1 && stack[top].v < now.v){
NGE[stack[top].i] = now.v;
stack[top--] = null;
}
if(top == -1 || stack[top].v >= now.v){
stack[++top] = now;
}
}
for (int value : NGE){
sb.append(value == 0? -1 : value).append(" ");
}
System.out.println(sb);
}
}
class Node {
int i;
int v;
public Node (int i, int v){
this.i = i;
this.v = v;
}
}
4. 성장하기
나는 해당 문제를 풀기 위해, 클래스를 사용하였다. 가독성 면에서는 좋지만, 속도 면에서 조금 느려질 수 있다. 그래서 책에 있는 풀이를 봤더니 다음과 같이 문제를 풀었다.
- stack에는 index만 push, pop 하고, value를 다른 배열(value)에 따로 저장해서, 이것을 통해 비교한다.
예를 들어, value[stack[top]] < value[i] (stack의 최상단에 있는 값과 현재 조회 중인 값을 비교) - 내가 클래스를 만들어서 index와 value를 묶어 관리하던 것을 index용 stack과 value용 배열로 나누어서 관리하는 것이다.
이렇게 푸니까, 조금이지만 속도가 줄어들었다.
5. 다른 풀이
import java.io.*;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int N = Integer.parseInt(br.readLine());
int [] value = new int[N]; // index에 해당하는 value 저장
int [] stack = new int[N]; // index 만 저장
int [] nge = new int[N]; // index 당 자신의 오큰수 저장
int top = -1;
StringTokenizer st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
value[i] = Integer.parseInt(st.nextToken());
}
stack[++top] = 0;
for (int i = 1; i < N; i++) {
// 현재 조회 중인 값보다 stack의 top 값이 작은 경우
while(top != -1 && value[stack[top]] < value[i]){
nge[stack[top--]] = value[i];
}
if(top == -1 || value[stack[top]] >= value[i]){
stack[++top] = i;
}
}
for (int now : nge){
sb.append(now == 0? -1 : now).append(" ");
}
System.out.println(sb);
}
}
'알고리즘 > 문제 풀이' 카테고리의 다른 글
[백준] 11003 최소값 찾기 java (0) | 2024.07.02 |
---|---|
[백준] 1377 버블소트 JAVA (0) | 2024.07.02 |
[백준] 11399 ATM (0) | 2024.07.02 |
[백준] 1253 좋다 (0) | 2024.06.28 |
[백준] 2018 수들의 합 5 Java 풀이 (0) | 2024.06.28 |