문제 링크 👉🏻 https://www.acmicpc.net/problem/17298
오른쪽에 있는 큰 수 중 가장 왼쪽에 있는 수를 구한다.
크기가 N인 수열 = , , ..., 이 있다. 수열의 각 원소 에 대해서 오큰수 NGE()를 구한다.
의 오큰수는 오른쪽에 있으면서 보다 큰 수 중에서 가장 왼쪽에 있는 수를 의미한다.
그러한 수가 없는 경우에 오큰수는 -1이다.
👉🏻일 때
NGE(1) = 5, NGE(2) = 7, NGE(3) = 7, NGE(4) = -1
입력과 저장
n과 n개의 수를 arr 배열에 저장한다.nge 각 원소의 오큰수를 저장한다. 해당 배열에는 오큰수가 없을 때를 대비하여 -1로 채워놓는다.stack 을 선언하고 int배열이 저장되도록 한다. new int[] {오큰수, index} 형식으로 저장한다.오큰수 구하기
arr 를 순회한다.arr보다 작으면 stack 에 현재arr 값과 인덱스 값을 푸쉬한다.arr 보다 크면 while 문을 실행한다.arr값과 해당 값의 인덱스가 저장된다. 팝한 인덱스값을 nge 의 인덱스에 대입하여 해당 값을 arr 의 값으로 저장한다.while 문은 스택에 값이 존재하고, 스택의 탑이 현재 arr 값보다 클동안 실행된다.출력
StringBuilder 를 사용하여 한 번에 출력하도록 한다.그림으로 설명하면 다음과 같다

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Stack;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Stack<int[]> stack = new Stack<>();
int n = Integer.parseInt(br.readLine());
int arr[] = new int[n];
int nge[] = new int[n];
Arrays.fill(nge, -1);
String[] input = br.readLine().split(" ");
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(input[i]);
}
for (int i = 0; i < n; i++) {
while (!stack.isEmpty() && stack.peek()[0] < arr[i]) {
int[] peek = stack.pop();
nge[peek[1]] = arr[i];
}
stack.add(new int[]{arr[i], i});
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
sb.append(nge[i] + " ");
}
System.out.println(sb);
}
}
문제 풀이를 어떤 방식으로 해야 할지 감이 잡히지 않아 알고리즘 분류를 확인하고 문제를 풀었다.
이전에 시도를 몇 번 해본 문제였다. 내 제출 내역을 보니 C++, 파이썬으로 총 3번의 시도가 있었고, 모두 ‘틀렸습니다’, ‘시간 초과’라는 결과가 나왔다.
제출했던 코드를 보니 정답을 도출해 내기에는 한참 모자란 코드 같다😅
한때는 C++, 한때는 파이썬이 가장 편한 언어였는데.. 어쩌다 보니 Java로 알고리즘 공부를 하게 됐고 이제 C++, 파이썬 두 언어는 기억이 가물가물 해져간다. 그래도.. 다시 공부를 시작하면 금방 익숙해질 수 있을 것 같은데… 일단 한 가지에 집중하자💪🏻
제출 기록들이 1년 전이었는데, 그때는 머리를 쥐어짜내도 해결 방법이 생각나지 않았다.
이번에는 정말 신기하게도 풀이 방법이 금방 떠올랐고, 그 방법이 맞았다. 문제를 많이, 다양하게 풀려고 노력 중인데, 그 노력이 빛을 발하고 있는 것 같아 뿌듯하다😝