Algorithm

[백준 BOJ] 17298 오큰수 C++

유자바 2024. 8. 1. 17:27

문제


https://www.acmicpc.net/problem/17298

 

입력

  • 수열 A의 크기
  • 수열 A의 원소들

출력

  • Ai의 오큰수
    • 오큰수: Ai의 오른쪽에 있고, Ai보다 큰 수이며, 큰 수들 중 가장 왼쪽에 있는 수
  • 오큰수가 없는 경우 -1 출력

 


 

풀이


  • 수열의 원소는 배열에 저장, 인덱스는 스택에 저장해 문제를 해결한다.
  • 스택에 저장되어 있는 수는 오큰수를 찾지 못한 원소이다.

 

세부 풀이

  • 배열에 수열의 원소 저장한다.
    • 이때 문제에 제시된 수열의 크기를 배열의 크기로 지정한다. (1 ≤ N ≤ 1,000,000)
    • 인덱스를 이용해 원소의 크기를 비교할 예정이기 때문에 인덱스 사용이 용이하도록 자료구조는 배열로 선택했다.
  • 원소의 인덱스를 스택에 저장한다.
    • 앞 원소(Ai-1)와 현재 원소(Ai)를 비교하기 위해 스택을 사용했는데, 스택은 LIFO(Last In First Out)으로 이미 스택에 저장된 값을 비교할 수 있다.
  • 0번 인덱스를 가장 먼저 스택에 저장했다.
  • 스택이 비어있지 않고, 이미 스택에 저장된 원소(Ai-1)와 현재 원소(Ai)의 값을 비교한다.
  • Ai-1가 Ai보다 작다면 결과 배열에 Ai를 저장한 후 스택에서 i-1을 제거해준다.
  • N번 동안 비교를 한 후 스택에 남아있는 원소가 있다면 이 원소는 오큰수가 없는 원소이므로 결과 배열에 -1을 저장해준다.

 

코드


#include <iostream>
#include <stack>
#define MAX 1000001
using namespace std;

int N;
int arr[MAX]={0,};
int nge[MAX]={0,};
stack <int> s;

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

    cin >> N;

    for (int i=0;i<N;i++) {
        cin >> arr[i];
    }

    for (int i=0;i<N;i++) {
        while (!s.empty() && arr[s.top()]<arr[i]) {
            nge[s.top()] = arr[i];
            s.pop();
        }
        s.push(i);
    }

    while (!s.empty()) {
        nge[s.top()] = -1;
        s.pop();
    }

    for (int i=0;i<N;i++){
        cout << nge[i] << " ";
    }

    return 0;
}

 


 

사실 처음에는 시간초과가 나왔었다.

냅다 이중 for문을 쓰는 바람에 시간 복잡도가 O(N^2)이 되어 30%쯤에서 시간초과가 나왔던 것 같다.

그리고 내가 봐도 내 코드가 별로였다.
자료구조로 벡터를 사용했는데 벡터의 장점을 활용하지 못하고 배열처럼 사용했다. 

flag 변수 사용하는거 안 좋아하는데 일단 코드를 돌리려고 flag 변수도 사용해버렸다. 

앞으로는 자료구조를 백번 활용할 수 있도록 왜 이 자료구조를 사용하는지 고민하는 연습을 해야겠다!!

내가 봐도 별로였던 코드.. 부끄럽지만 첨부합니다🤧

#include <iostream>
#include <vector>
using namespace std;

int N;

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

    cin >> N;
    vector <int> v(N);

    for (int i=0;i<N;i++){
        cin >> v[i];
    }

    int size = v.size()-1;
    for (int i=0;i<N;i++){
        int flag = false;
        int cur = v[i];

        for (int j=i;j<N;j++){
            if (cur < v[j+1]){
                cout << v[j+1] << " ";
                flag = true;
                break;
            }
        }

        if (i == size || !flag){
            cout << "-1 ";
        }
    }
    cout << '\n';

    return 0;
}