백준 단계별로 풀어보기 [스택] 오큰수
https://www.acmicpc.net/problem/17298
17298번: 오큰수
첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에 수열 A의 원소 A1, A2, ..., AN (1 ≤ Ai ≤ 1,000,000)이 주어진다.
www.acmicpc.net
[풀이]
스택의 top에 저장된 인덱스의 배열 값과 비교하여 현재 배열 값이 더 크면 오큰수를 발견한 것이다. 따라서 오큰수를 발견한 값의 인덱스는 스택에서 pop해 지워준다. 오큰수에 해당하는 값은 ans[] 배열에 저장해준다.
스택의 top보다 현재 배열값이 더 작아지면 현재 배열값을 stack에 push해준다.
for문이 종료되면 stack이 빌 때까지 stack에 남은 index에 대해 오큰수가 존재하지 않는 것이므로 ans[] 배열에 -1을 저장한다.
예) [3, 5, 2, 7]
index: 0 -> push(0) stack: (top) 0(3)
index: 1 -> arr[1] = 5 > arr[0] = 3이기 때문에 ans[] 저장 후 pop(). while 문 나와서 push(1).
stack: (top) 1(5) ans: [5, , , ]
index: 2 -> arr[2] = 2 < arr[1] = 5이기 때문에 push(2). stack: (top) 2(2) 1(5) ans: [5, , , ]
index: 3 -> arr[3] = 7 > arr[2] = 2이기 때문에 ans: [5, , 7, ] 저장 후 pop().
> arr[1] = 5이기 때문에 ans: [5, 7, 7, ] 저장 후 pop(). while문 나와서 push(3).
for문 나와서 ans[3] = -1 저장. ans: [5, 7, 7, -1].
[코드]
#include <iostream>
#include <algorithm>
#include <stack>
int main() {
// 스택 오큰수
int n; //수열의 크기
std::cin >> n;
std::stack<int> s;
int* arr = new int[n];
int* ans = new int[n];
for (int i = 0; i < n; i++) {
std::cin >> arr[i];
}
for (int i = 0; i < n; i++) {
if (s.empty())
s.push(i);
while (!s.empty() && arr[i] > arr[s.top()]) { //오큰수 발견
ans[s.top()] = arr[i];
s.pop();
}
s.push(i);
}
while (!s.empty()) {
ans[s.top()] = -1;
s.pop();
}
for (int i = 0; i < n; i++)
std::cout << ans[i] << " ";
delete[] arr, ans;
}
'알고리즘 공부 및 문제 풀이 > 백준(BOJ)' 카테고리의 다른 글
[c++] 백준 11279, 1927 최대 힙, 최소 힙 (0) | 2021.08.07 |
---|---|
[c++] 백준 1018 체스판 다시 칠하기 (0) | 2021.08.06 |
[c++] 9461 파도반 수열 (0) | 2021.08.04 |
[c++] 백준 2156 포도주 시식 (0) | 2021.08.03 |
[c++] 백준 9663 N-Queen (0) | 2021.08.02 |