Algorithm/Baekjoon

백준 17298번 오큰수 (Java)

swoody 2024. 9. 6. 22:31

문제

백준 17298번 나머지 합 / 골드4
크기가 N인 수열 A = A1, A2, ..., AN이 있다. 수열의 각 원소 Ai에 대해서 오큰수 NGE(i)를 구하려고 한다. Ai의 오큰수는 오른쪽에 있으면서 Ai보다 큰 수 중에서 가장 왼쪽에 있는 수를 의미한다. 그러한 수가 없는 경우에 오큰수는 -1이다.
예를 들어, A = [3, 5, 2, 7]인 경우 NGE(1) = 5, NGE(2) = 7, NGE(3) = 7, NGE(4) = -1이다. A = [9, 5, 4, 8]인 경우에는 NGE(1) = -1, NGE(2) = 8, NGE(3) = 8, NGE(4) = -1이다.

입력

첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에 수열 A의 원소 A1, A2, ..., AN (1 ≤ Ai ≤ 1,000,000)이 주어진다.

풀이

stack을 활용한 문제이다. 단순히 모든 구간을 비교하게 되면 입력 N이 106이므로 시간복잡도는 O(n2)로 시간 초과가 발생한다.

그래서 당장 오큰수를 구하지 못한 원소Ai들의 인덱스 iindexStack에 저장해주었다. 그리고 매번 새로운 수가 들어올 때마다 스택에 저장된 인덱스를 활용해 Ai의 오큰수 검사를 해줬다.

모든 인덱스에 대한 검사가 종료 후, 스택에 남은 인덱스들은 오큰수가 없는 케이스들로 -1을 결과에 넣어주며 마무리했다.

코드

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());

        StringTokenizer st = new StringTokenizer(br.readLine());
        int[] input = new int[N];
        int[] result = new int[N];
        for (int i = 0; i < N; i++) {
            input[i] = Integer.parseInt(st.nextToken());
        }

        Stack<Integer> indexStack = new Stack<Integer>();
        indexStack.push(0);
        for (int i = 1; i < N; i++) {
            while (!indexStack.isEmpty() && input[indexStack.peek()] < input[i]) {
                result[indexStack.pop()] = input[i];
            }
            indexStack.push(i);
        }

        while (!indexStack.isEmpty()) {
            result[indexStack.pop()] = -1;
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < N; i++) {
            sb.append(result[i]).append(" ");
        }

        System.out.println(sb.toString());
    }
}

'Algorithm > Baekjoon' 카테고리의 다른 글

백준 1517번 버블 소트 (Java)  (0) 2024.09.16
백준 1377번 버블 소트 (Java)  (2) 2024.09.07
백준 11003번 최솟값 찾기 (Java)  (0) 2024.09.03
백준 1253번 좋다 (Java)  (4) 2024.09.02
백준 10986번 나머지 합 (Java)  (3) 2024.09.01