[백준 17298번] 오큰수
Updated:
문제 화면
문제 링크 : https://www.acmicpc.net/problem/17298
문제 풀이
이 문제는 stack의 자료구조를 응용하는 문제이다. 문제의 핵심은 현재 숫자 기준으로 오큰수를 찾는 것이 아닌 오큰수가 되는 숫자 관점에서 생각해야 되는 부분이다. 스택 특성상 왼쪽에서 오른쪽을 생각했을 때 풀이가 떠오르지 않으면 오른쪽에서 왼쪽으로 생각하면 풀리는 경우가 많은 것 같다.
기존의 스택 문제들과 큰 차이가 없어서 문제를 푸는 데에 큰 어려움은 없었지만 문제를 풀고 나서 다른 사람들의 코드와 비교하면서 내 코드가 여러 부분에서 비효율적이라는 생각이 들어서 최적화를 해보았다. 문제를 맞추는 것에 만족하는 것이 아닌 맞추고 나서 어떻게 하면 더 좋은 코드가 될 수 있었을까 복기하는 습관도 중요한 것 같다.
제출 코드
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
vector<int> v;
stack<int> p;
stack<int> s;
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int a, temp;
cin >> a;
for(int i = 0 ; i < a ; i++) {
cin >> temp;
v.push_back(temp);
}
for(int i = v.size()-1 ; i >=0 ; i--) {
if(s.empty()) p.push(-1); // 마지막 번호는 무조건 -1이기 때문에 넣어준다.
while(!s.empty()) {
if(s.top() > v[i]) {
p.push(s.top());
break;
} // 찾으면 while문 나가라
else {
s.pop();
if(s.empty()) {
p.push(-1);
}
}
} // 오큰수 찾을때까지 pop
s.push(v[i]);
}
while(!p.empty()) {
cout << p.top() << " ";
p.pop();
}
return 0;
}
제출 코드(최적화)
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
// vector<int> v;
// stack<int> p;
int A[1000001];
int P[1000001];
// 배열이 더 빠르다. 굳이 벡터나 스택 쓰지 말자.
stack<int> s;
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int a;
cin >> a;
for(int i = 0 ; i < a ; i++) cin >> A[i];
for(int i = a-1 ; i >=0 ; i--) {
while(!s.empty() && s.top() <= A[i]) s.pop();
// empty()와 크기를 동시에 비교
// 코드가 더 짧아지고 기존 코드와 같이 pop() 조건을 두번씩 확인할 필요가 없음
// 이 while문을 빠져나가면 1. 스택이 비어있거나 2. 더 큰 오큰수만 남게 된다.
if(s.empty()) P[i] = -1;
// 1. 스택이 비어있는 경우 오큰수가 없다는 뜻이기 때문에 -1을 정답 배열에 저장
// 주의할 점은 s.top()을 확인하기 전에 empty()를 먼저 확인해주어야 한다!(처음에 s.top()을 먼저 넣어주어서 오답이 떴다)
else P[i] = s.top();
// 2. 더 큰 오큰수만 남아있는 경우이기 때문에 바로 정답 배열에 넣어주면 된다.
s.push(A[i]);
// 현재 숫자를 스택에 넣어준다.
}
for(int i = 0 ; i < a ; i++) {
cout << P[i] << " ";
}
return 0;
}
결론
다른 스택 문제들과 크게 다르지 않았지만 코드를 최적화 할 수 있는 부분들을 찾아서 앞으로 문제를 풀 때 많은 도움이 될 것 같다.
Leave a comment