λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
Algorithm/λ°±μ€€(BOJ)

[ 파이썬(python) ] λ°±μ€€ 2493 - 탑

by YWTechIT 2021. 7. 9.
728x90

πŸ“ λ°±μ€€ 2493 - 탑

문제: λ°±μ€€ 2493 - 탑


πŸ’‘ λ‚˜μ˜ 풀이

μŠ€νƒμ„ ν™œμš©ν•˜λ©΄ λ˜λŠ” 문제인데 λ¨Έλ¦Ώμ†μœΌλ‘œλŠ” λ‹¨κ³„λ³„λ‘œ 생각이 잘 λλŠ”λ° μ½”λ“œλ‘œ κ΅¬ν˜„ν•˜λ €λ‹ˆκΉŒ 쉽지 μ•Šμ•˜λ‹€. μš°μ„  λ²”μœ„κ°€ 500,000이기 λ•Œλ¬Έμ— 이쀑 λ°˜λ³΅λ¬Έμ„ μ‚¬μš©ν•˜λ©΄ μ΅œλŒ€ 250,000,000,000κΉŒμ§€μž„μ„ λͺ…심해야 ν•œλ‹€. μ—¬κΈ°μ„œ μ˜λ¬Έμ μ€ μ„±κ³΅μ½”λ“œμ™€ μ‹€νŒ¨ μ½”λ“œμ˜ μ‹œκ°„ λ³΅μž‘λ„μ˜ μ°¨μ΄λŠ” (index, slicing)의 차이인것 같은데 μ™œ μ‹œκ°„μ΄ˆκ³Όκ°€ λ‚˜λŠ”μ§€ 잘 λͺ¨λ₯΄κ² λ‹€.(κ³ μˆ˜λ‹˜λ“€ λŒ“κΈ€λΆ€νƒλ“œλ¦½λ‹ˆλ‹€ :))

 

---

[ 21. 7. 13. ]

백쀀에 μ‹œκ°„μ΄ˆκ³Ό κ΄€λ ¨ν•˜μ—¬ μ§ˆλ¬Έμ„ λ‚¨κ²ΌλŠ”λ° @djm03178λ‹˜κ»˜μ„œ 쒋은 닡변을 ν•΄μ£Όμ…¨λ‹€. 결둠적으둜 μ‹œκ°„λ³΅μž‘λ„λŠ” λ‹€μŒκ³Ό κ°™λ‹€.

 

1. μ„±κ³΅μ½”λ“œ(O(N)): 각 μ›μ†Œκ°€ μŠ€νƒμ— λ“€μ–΄κ°€κ³  λ‚˜μ˜€λŠ” 연산이 ν•œ λ²ˆμ”©λ§Œ μˆ˜ν–‰λœλ‹€.

2. slicing(O(N^2)): 각 μ›μ†Œλ§ˆλ‹€ `slicing`을 μˆ˜ν–‰ν•˜λŠ”λ° λŒ€μƒ μ›μ†Œμ˜ μˆ˜κ°€ 1λΆ€ν„° `N`κΉŒμ§€ 계속 μ¦κ°€ν•˜κ³  `slicing`의 μ‹œκ°„λ³΅μž‘λ„λŠ” μ›μ†Œμ˜ μˆ˜μ™€ λΉ„λ‘€ν•˜λ―€λ‘œ `O(N^2))`이 λœλ‹€.

3. index(O(N^2)): 각 μ›μ†Œλ§ˆλ‹€ `index`ν•¨μˆ˜κ°€ ν•΄λ‹Ή μ›μ†Œλ₯Ό μ°ΎκΈ° μœ„ν•΄ 리슀트λ₯Ό μ²˜μŒλΆ€ν„° λκΉŒμ§€ μˆœνšŒν•˜κΈ°λ•Œλ¬Έμ— μ—­μ‹œ `O(N^2))`κ°€ λœλ‹€.

 

λ‘λ²ˆμ§Έ μ„Έλ²ˆμ§Έ μ½”λ“œλŠ” 이해가 잘 λμœΌλ‚˜ 첫번째 μ½”λ“œκ°€ μ™œ `O(N)` 인지 이해가 μ•ˆλΌμ„œ μ§ˆλ¬Έμ„ λ‚¨κ²Όλ”λ‹ˆ λ‹€μŒκ³Ό 같은 닡변을 λ°›μ•˜λ‹€.

 

" 첫번째 μ½”λ“œμ—μ„œ 이쀑 λ°˜λ³΅λ¬Έμ„ 각각 μ΅œμ•…μ˜ 경우 `O(N)`λ²ˆμ”© λˆλ‹€κ³  μƒκ°ν•΄μ„œ `for * while = O(N^2)` 이라고 νŒλ‹¨ν•˜λ©΄ μ•ˆλœλ‹€. 만일 λ°”κΉ₯ 루프가 ν•œλ²ˆ 돌 λ•Œ 운이 μ•ˆ μ’‹μ•„μ„œ μ•ˆμͺ½ λ£¨ν”„μ˜ `N`개의 μ›μ†Œλ₯Ό popν–ˆλ‹€κ³  κ°€μ •ν•˜λ©΄, κ·Έ ν•œλ²ˆμ˜ 루프λ₯Ό μ œμ™Έν•œ λ‚˜λ¨Έμ§€λŠ” λͺ¨λ‘ `pop`을 μ•ˆν–ˆλ‹€λŠ” 것이닀.(while stack: μ‘°κ±΄λ•Œλ¬Έμ—) 즉, 아무리 루프λ₯Ό 였래 돌리렀고 해도 μ•ˆμͺ½ 루프가 Nλ²ˆλ³΄λ‹€ 많이 돌 수 λŠ” μ—†λ‹€.

 

μ–Έμ  κ°€ 많이 돈 λ•Œκ°€ μžˆλ‹€λ©΄, λ‹€λ₯Έ λ•ŒλŠ” 많이 μ•ˆ λŒμ•˜μ–΄μ•Όλ§Œ ν•˜κ³  총 횟수 μ—­μ‹œ  `O(N)`밖에 μ•ˆλœλ‹€. 즉, μ•ˆμͺ½ 루프가 λ„λŠ” 총 횟수λ₯Ό λ‹€ ν•©ν–ˆμ„ λ•Œ `O(N)`μ΄λΌλŠ” 큰 그림을 λ³΄λŠ”κ²Œ μ€‘μš”ν•˜μ§€, λ°”κΉ₯ 루프가 ν•œ 번 λŒλ•Œ μ•ˆμͺ½ 루프가 μ΅œλŒ€ `O(N)`번 λ„λŠ” 그림은 λ³Ό ν•„μš”κ°€ μ—†λ‹€λŠ” λœ»μ΄λ‹€. 이 μ½”λ“œμ˜ μ΅œμ•…μ˜ κ²½μš°μ—λ„ 전체가 `O(N)`이닀. "

 

라고 닡글을 λ‹¬μ•„μ£Όμ…¨λŠ”λ°.. ꡉμž₯히 λ©‹μžˆμœΌμ…¨λ‹€. λ‚˜λ„ μ—΄μ‹¬νžˆ κ³΅λΆ€ν•΄μ„œ μ €λΆ„μ²˜λŸΌ 닡글을 달아쀄 수 μžˆλŠ” 날이 μ™”μœΌλ©΄ μ’‹κ² λ‹€. λ‹΅λ³€κ³Ό ν•¨κ»˜ λΆ„ν• μƒν™˜λΆ„μ„ 링크도 μ£Όμ…¨λŠ”λ° ν•œλ²ˆ μ‚΄νŽ΄λ΄μ•Όκ² λ‹€. 

---

 

μ‹€νŒ¨ μ½”λ“œλŠ” λ’€μ—μ„œλΆ€ν„° λΉ„κ΅ν–ˆκ³  μ„±κ³΅μ½”λ“œλŠ” μ•žμ—μ„œλΆ€ν„° λΉ„κ΅ν–ˆλ‹€. μ„±κ³΅μ½”λ“œμ˜ 풀이 방법을 보자.

 

  1. stack이 μ‘΄μž¬ν•˜λŠ” λ™μ•ˆμ— 이전에 λ“€μ–΄μ˜¨ stack[-1][1]의 κ°’κ³Ό μ§€κΈˆ λ“€μ–΄μ˜¬ top[i]의 값을 λΉ„κ΅ν•œλ‹€.
  2. λ§Œμ•½, 이전에 λ“€μ–΄μ˜¨ stack[-1][1]의 값이 top[i] 보닀 크면 λ ˆμ΄μ € μ‹ ν˜Έλ₯Ό μˆ˜μ‹ ν•  수 있기 λ•Œλ¬Έμ— κ·Έλ•Œμ˜ stack[-1][0](index)λ₯Ό μ €μž₯ν•œλ‹€.
  3. 그렇지 μ•ŠμœΌλ©΄, λ‹€μŒμœΌλ‘œ μ‘΄μž¬ν•˜λŠ” stack값을 ν™•μΈν•˜κΈ° μœ„ν•΄ pop()ν•œλ‹€.
  4. stack에 아무것도 남지 μ•ŠμœΌλ©΄ [i, top[i]]값을 λ„£λŠ”λ‹€.(μ΄λ•Œ, iλ₯Ό λ„£λŠ” μ΄μœ λŠ” indexλ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•¨μ΄λ‹€.)

 

이해가 잘 μ•ˆ 되면 λ‹€μŒ 사진을 보자.

 

 

# 성곡 μ½”λ“œ
n = int(input())
top = list(map(int, input().split()))
stack = []
answer = [0 for i in range(n)]

for i in range(n):
    while stack:
        if stack[-1][1] > top[i]:
            answer[i] = stack[-1][0] + 1
            break
        else:
            stack.pop()
    stack.append([i, top[i]])

print(*answer)

 

n = int(input())
top = list(map(int, input().split()))
index = [0] * n

# μ‹œκ°„ 초과 μ½”λ“œ: slicing ν•¨μˆ˜ μ‚¬μš©
for i in range(1, n):
    stack = top[:n - i]
    index_value = len(stack)

    while stack:
        if stack[-1] > top[n - i]:  # ν˜„μž¬ 값보닀 탑이 더 크면
            high_top = stack[-1]
            index[n - i] = index_value
            break
        else:    # ν˜„μž¬ 값보닀 탑이 μž‘κ±°λ‚˜ κ°™μœΌλ©΄
            index_value -= 1
            stack.pop()

# μ‹œκ°„ 초과 λ‘λ²ˆμ§Έ μ½”λ“œ: index ν•¨μˆ˜ μ‚¬μš©
for i in range(1, n):
    stack = top[:n-i]

    while stack:
        if stack[-1] > top[n-i]:    # ν˜„μž¬ 값보닀 탑이 더 크면
            high_top = stack[-1]
            index[n-i] = top.index(high_top) + 1
            break
        else:
            stack.pop()

print(' '.join(map(str, index)))
λ°˜μ‘ν˜•

λŒ“κΈ€