[C++] 백준(BOJ) - 17298 : 오큰수
인프런에 있는 큰돌님의 강의 10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트를 듣고 정리한 필기입니다.
문제
크기가 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
알고리즘
- 시간복잡도
- 스택
풀이
- 오큰수는 오른쪽에 있다
- 오큰수가 나오기 전에 미리 저장해 놓기 => 스택 자료구조를 활용
- 오큰수가 나와서 이전 담아 놓은 값들의 오큰수가 결정된다면 배열에 값 (오큰수)저장
코드
// 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문이 아닌 다른 방법을 생각해야한다
- 짝짓기 문제는 스택을 항상 생각해보기