알고리즘 자료구조/Stack

BOJ 17298번 오큰수 (Stack) Python

Zeta050525 2022. 1. 3. 13:30
728x90

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

문제

크기가 N인 수열 A = A1, A2,..., AN이 있다. 수열의 각 원소 Ai에 대해서 오 큰 수 NGE(i)를 구하려고 한다. Ai의 오 큰 수는 오른쪽에 있으면서 Ai보다 큰 수 중에서 가장 왼쪽에 있는 수를 의미한다. 그러한 수가 없는 경우에 오 큰 수는 -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의 원소 A1, A2, ..., AN (1 ≤ Ai ≤ 1,000,000)이 주어진다.

 

출력

총 N개의 수 NGE(1) ~ NGE(N)을 공백으로 구분해 출력한다.

 

NGE 오큰수?

 오 큰 수는 오른쪽에 있으면서 Ai보다 큰 수 중에서 가장 왼쪽에 있는 수를 의미한다.

3 2 4 8 9

NGE(n) n은 index입니다

n 이 1이라고 치면 3보다 크면서 오른쪽에 있는 수는

8,9가 되겠네요 여기서 가장 왼쪽에 있는 수는 8입니다.

 

내가 접근한 방법

그냥 스택안쓰고 어거지로 2중 for문써서

arr[index(n)]보다 큰 수가 나오면 바로 break 했는데

A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다

백만 개의 숫자가 입력되기 때문에 당연히 시간 초과가 납니다. (0(n^2))

당연한 건데 저는 4번이나 똑같은 방법으로 시간 초과를 받았습니다.

이 문제는 스택을 활용해서 2중 for문을 사용하지 않고해결할 수 있습니다.

처음엔 도대체 for문을 쓰지않고 나보고 도대체 어쩌라는건가 싶었는데

풀고나서 티어보니까 골드4문제더라구요 원래 어려운문제같습니다.

 

풀이(python)

 

n = int(input())
arr = list(map(int, input().split()))

Oken = [-1] * n
stack = [0]



for i in range(1,n):
    if arr[i] > arr[stack[-1]] and stack:
        while(stack):
            if arr[stack[-1]] < arr[i] : 
                Oken[stack.pop()] = arr[i]
            else: 
                break
        stack.append(i)
    else:
        stack.append(i)
print(*Oken)

5

3 2 4 8 9

이게 입력으로 들어왔다 하겠습니다.

arr = [3 2 4 8 9]

오 큰 수를 담는  Oken배열을 만들어줍니다.

Oken = [-1] * n

그리고 스택을 하나 만들어줍니다

stack = [0] 스택에는 index를 넣어줄 겁니다

for문을 돌리는데 1부터 시작합니다.

arr [stack [-1]] < arr [i]

arr [stack [-1]]은 3이고

arr [i]는 2죠

작으니까 stack에 i를 넣어줍니다(1)

stack = [0,1]

이제 i는 2이고

arr [stack [-1]] < arr [i] 이걸 다시 하면

2 < 4

이렇게 큰 수를 만났을 때는 스택이 빌 때까지 //stack = [0,1]

arr [stack [-1] ] < arr [i]이라면

Oken [stack.pop()]에 4(오 큰 수)를 넣어줍니다. //pop은 최상단의 원소를 리턴하고 삭제합니다

이 과정을 마치면

Oken  = [4,4,-1~]

이 되어있겠죠

 

이 문제는 자료구조의 중요성을 느끼게 해 주는 엄청 좋은 문제 같습니다

 

 

 

728x90