알고리즘/node.js

[백준/Node.js] 17298번: 오큰수

minliz 2025. 3. 4. 17:40

목차

📝 문제

🎯 알고리즘 핵심 단계

✅ 실습 인증 파트_코드

⚡ 트러블 슈팅

🤔 이것도 한 번 생각해봐요! (참고 자료)


 

https://www.acmicpc.net/problem/17298

 

📝 문제

크기가 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)이 주어진다.

 

출력

총 N개의 수 NGE(1), NGE(2), ..., NGE(N)을 공백으로 구분해 출력한다.

 


🎯 알고리즘

💡 문제 이해

 오큰수: 배열에서 각 원소의 오른쪽에 있는 숫자 중에서 제일 처음으로 나오는 크기가 더 큰 숫자

 

- 배열에서 왼쪽-> 오른쪽으로 탐색

- 현재 숫자의 오른쪽에 있는 숫자들만 비교

- 더 큰 숫자를 찾으면 바로 기록

- 만약에 못 찾으면 -1 기록

 

💡 문제 접근

 

스택 사용!

단순하게 for문 2개로 풀면 ->  배열의 크기가 100만이면 시간 초과

==> 스택 활용

🧠 아이디어 흐름

  1. 스택에는 인덱스만 저장합니다.
  2. 스택에 있는 인덱스는 아직 오큰수를 찾지 못한 숫자들입니다.
  3. 새로운 숫자가 들어오면:
    • 스택 맨 위 숫자와 비교합니다.
    • 현재 숫자가 더 크면:
      • 스택에서 꺼냅니다.
      • 그 인덱스에 오큰수 기록
  4. 비교가 끝나면 현재 인덱스를 스택에 넣습니다.

✅ 실습 인증 _코드

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split("\n");

const N = parseInt(input[0]);
const list = input[1].split(" ").map(Number);

let stack=[];
let result = Array(N).fill(-1);

for (let i = 0; i < N; i++) {
    while(stack.length>0 && list[stack[stack.length-1]] <list[i]){
        result[stack.pop()] = list[i];
    }
    stack.push(i);
}

console.log(result.join(" "));

 


⚡ 트러블 슈팅

       🌱

 


🤔 이것도 한 번 생각해봐요! (참고 자료)