코딩테스트/백준
[백준 C++] 17298. 오큰수
tkxx_ls
2024. 4. 17. 20:57
문제 링크
17298번: 오큰수
첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에 수열 A의 원소 A1, A2, ..., AN (1 ≤ Ai ≤ 1,000,000)이 주어진다.
www.acmicpc.net
접근 방법
수열의 크기가 최대 1,000,000이므로 brute-force로 찾게 되면 시간 복잡도는 n^2이 되기 때문에 시간초과가 나게 됩니다.
따라서 stack을 사용하여 O(n^2)을 O(n)으로 최적화해서 문제를 해결합니다.
소스 코드
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
int n;
cin >> n;
vector<int> num(n), answer(n, -1);
for (auto &a : num)
cin >> a;
stack<int> s;
for (int i = 0; i < n; i++)
{
while(!s.empty() && num[s.top()] < num[i])
{
answer[s.top()] = num[i];
s.pop();
}
s.emplace(i);
}
for (auto &a : answer)
cout << a << ' ';
return 0;
}
코드 설명
오른쪽에 큰 수가 없을 때 -1을 출력해야 하므로 미리 ans 배열을 -1로 초기화합니다.
스택에는 수열의 인덱스를 넣습니다. 스택의 top 은 항상 i 보다 작은 인덱스입니다.
즉 num[s.top()] < num[i] 를 만족하게 되면 num[s.top()] 보다 오른쪽에 있으면서
num[s.top()] 보다 큰 수 중에서 가장 왼쪽에 있는 수를 의미하게 됩니다.
오큰수를 찾게 되면 해당 인덱스는 더 이상 확인해 줄 필요가 없으므로 pop 해주며
ans 배열에 s.top에 해당하는 인덱스에 오큰수를 넣어줍니다.
그리고 스택에 들어있는 이전 인덱스들에 대해서도 오큰수를 만족하는지 확인합니다.
스택이 단조 감소 스택을 만족하기 때문에 스택의 top만 확인해 줍니다.