[C++] 백준(BOJ) - 17298 : 오큰수

인프런에 있는 큰돌님의 강의 10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트를 듣고 정리한 필기입니다.

문제

백준(BOJ) - 17298 : 오큰수(링크)

크기가 N인 수열 $A$ = $A_1$, $A_2$, …, $A_N$이 있다. 수열의 각 원소 $A_i$에 대해서 오큰수 NGE(i)를 구하려고 한다. $A_i$의 오큰수는 오른쪽에 있으면서 $A_i$보다 큰 수 중에서 가장 왼쪽에 있는 수를 의미한다. 그러한 수가 없는 경우에 오큰수는 -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의 원소 $A_1$, $A_2$, …, $A_N$ (1 ≤ $A_i$ ≤ 1,000,000)이 주어진다.

출력

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

입력 예제

4
3 5 2 7

출력 예제

5 7 7 -1

알고리즘

  1. 시간복잡도
  2. 스택

풀이

  • 오큰수는 오른쪽에 있다
  • 오큰수가 나오기 전에 미리 저장해 놓기 => 스택 자료구조를 활용
  • 오큰수가 나와서 이전 담아 놓은 값들의 오큰수가 결정된다면 배열에 값 (오큰수)저장

코드

// BOJ-17298 : 오큰수
#include<bits/stdc++.h>
using namespace std;

int v[1000004], n, res[1000004];

stack<int> stk;

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	cin >> n;

	fill(res, res + 1000004, -1);

	for (int i = 0; i < n; i++)
	{
		cin >> v[i];
		while (stk.size() && v[stk.top()] < v[i])
		{
			res[stk.top()] = v[i];
			stk.pop();
		}
		stk.push(i);
	}

	for (int i = 0; i < n; i++) cout << res[i] << ' ';
	

	return 0;
}

평가

  • 시간복잡도가 넘어가는 문제는 이중 for문이 아닌 다른 방법을 생각해야한다
  • 짝짓기 문제는 스택을 항상 생각해보기

© 2023 Jinsoo Lee. All rights reserved.

Powered by Hydejack v9.1.6