🐍 μ½”λ”©ν…ŒμŠ€νŠΈ λŒ€λΉ„ : PS

[ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€] 보석 μ‡Όν•‘ (level3, python)

개발자 HOON 2022. 10. 10. 21:48

🏝 문제 μ„€λͺ…

[λ³Έ λ¬Έμ œλŠ” μ •ν™•μ„±κ³Ό νš¨μœ¨μ„± ν…ŒμŠ€νŠΈ 각각 μ μˆ˜κ°€ μžˆλŠ” λ¬Έμ œμž…λ‹ˆλ‹€.]

 

개발자 μΆœμ‹ μœΌλ‘œ 세계 졜고의 κ°‘λΆ€κ°€ 된 μ–΄ν”ΌμΉ˜λŠ” 슀트레슀λ₯Ό 받을 λ•Œλ©΄ 이λ₯Ό ν’€κΈ° μœ„ν•΄ μ˜€ν”„λΌμΈ 맀μž₯에 쇼핑을 ν•˜λŸ¬ κ°€κ³€ ν•©λ‹ˆλ‹€.
μ–΄ν”ΌμΉ˜λŠ” 쇼핑을 ν•  λ•Œλ©΄ 맀μž₯ μ§„μ—΄λŒ€μ˜ νŠΉμ • λ²”μœ„μ˜ 물건듀을 λͺ¨λ‘ 싹쓸이 κ΅¬λ§€ν•˜λŠ” μŠ΅κ΄€μ΄ μžˆμŠ΅λ‹ˆλ‹€.
μ–΄λŠ λ‚  슀트레슀λ₯Ό ν’€κΈ° μœ„ν•΄ 보석 맀μž₯에 쇼핑을 ν•˜λŸ¬ κ°„ μ–΄ν”ΌμΉ˜λŠ” μ΄μ „μ²˜λŸΌ μ§„μ—΄λŒ€μ˜ νŠΉμ • λ²”μœ„μ˜ 보석을 λͺ¨λ‘ κ΅¬λ§€ν•˜λ˜ νŠΉλ³„νžˆ μ•„λž˜ λͺ©μ μ„ λ‹¬μ„±ν•˜κ³  μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€.


<μ§„μ—΄λœ λͺ¨λ“  μ’…λ₯˜μ˜ 보석을 적어도 1개 이상 ν¬ν•¨ν•˜λŠ” κ°€μž₯ 짧은 ꡬ간을 μ°Ύμ•„μ„œ ꡬ맀>

 

예λ₯Ό λ“€μ–΄ μ•„λž˜ μ§„μ—΄λŒ€λŠ” 4μ’…λ₯˜μ˜ 보석(RUBY, DIA, EMERALD, SAPPHIRE) 8κ°œκ°€ μ§„μ—΄λœ μ˜ˆμ‹œμž…λ‹ˆλ‹€.


 

μ§„μ—΄λŒ€μ˜ 3λ²ˆλΆ€ν„° 7λ²ˆκΉŒμ§€ 5개의 보석을 κ΅¬λ§€ν•˜λ©΄ λͺ¨λ“  μ’…λ₯˜μ˜ 보석을 적어도 ν•˜λ‚˜ 이상씩 ν¬ν•¨ν•˜κ²Œ λ©λ‹ˆλ‹€.

μ§„μ—΄λŒ€μ˜ 3, 4, 6, 7번의 λ³΄μ„λ§Œ κ΅¬λ§€ν•˜λŠ” 것은 쀑간에 νŠΉμ • ꡬ간(5번)이 λΉ μ§€κ²Œ λ˜λ―€λ‘œ μ–΄ν”ΌμΉ˜μ˜ μ‡Όν•‘ μŠ΅κ΄€μ— λ§žμ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

 

μ§„μ—΄λŒ€ 번호 μˆœμ„œλŒ€λ‘œ λ³΄μ„λ“€μ˜ 이름이 μ €μž₯된 λ°°μ—΄ gemsκ°€ λ§€κ°œλ³€μˆ˜λ‘œ μ£Όμ–΄μ§‘λ‹ˆλ‹€. μ΄λ•Œ λͺ¨λ“  보석을 ν•˜λ‚˜ 이상 ν¬ν•¨ν•˜λŠ” κ°€μž₯ 짧은 ꡬ간을 μ°Ύμ•„μ„œ return ν•˜λ„λ‘ solution ν•¨μˆ˜λ₯Ό μ™„μ„±ν•΄μ£Όμ„Έμš”.


κ°€μž₯ 짧은 κ΅¬κ°„μ˜ μ‹œμž‘ μ§„μ—΄λŒ€ λ²ˆν˜Έμ™€ λ μ§„μ—΄λŒ€ 번호λ₯Ό μ°¨λ‘€λŒ€λ‘œ 배열에 λ‹΄μ•„μ„œ return ν•˜λ„λ‘ ν•˜λ©°, λ§Œμ•½ κ°€μž₯ 짧은 ꡬ간이 μ—¬λŸ¬ 개라면 μ‹œμž‘ μ§„μ—΄λŒ€ λ²ˆν˜Έκ°€ κ°€μž₯ μž‘μ€ ꡬ간을 return ν•©λ‹ˆλ‹€.


[μ œν•œμ‚¬ν•­]
  • gems λ°°μ—΄μ˜ ν¬κΈ°λŠ” 1 이상 100,000 μ΄ν•˜μž…λ‹ˆλ‹€.
    • gems λ°°μ—΄μ˜ 각 μ›μ†ŒλŠ” μ§„μ—΄λŒ€μ— λ‚˜μ—΄λœ 보석을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
    • gems λ°°μ—΄μ—λŠ” 1번 μ§„μ—΄λŒ€λΆ€ν„° μ§„μ—΄λŒ€ 번호 μˆœμ„œλŒ€λ‘œ 보석이름이 μ°¨λ‘€λŒ€λ‘œ μ €μž₯λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.
    • gems λ°°μ—΄μ˜ 각 μ›μ†ŒλŠ” 길이가 1 이상 10 μ΄ν•˜μΈ μ•ŒνŒŒλ²³ λŒ€λ¬Έμžλ‘œλ§Œ κ΅¬μ„±λœ λ¬Έμžμ—΄μž…λ‹ˆλ‹€.

μž…μΆœλ ₯ 예
["DIA", "RUBY", "RUBY", "DIA", "DIA", "EMERALD", "SAPPHIRE", "DIA"] [3, 7]
["AA", "AB", "AC", "AA", "AC"] [1, 3]
["XYZ", "XYZ", "XYZ"] [1, 1]
["ZZZ", "YYY", "NNNN", "YYY", "BBB"] [1, 5]
 

μž…μΆœλ ₯ μ˜ˆμ— λŒ€ν•œ μ„€λͺ…

 

μž…μΆœλ ₯ 예 #1
문제 μ˜ˆμ‹œμ™€ κ°™μŠ΅λ‹ˆλ‹€.

 

μž…μΆœλ ₯ 예 #2
3μ’…λ₯˜μ˜ 보석(AA, AB, AC)을 λͺ¨λ‘ ν¬ν•¨ν•˜λŠ” κ°€μž₯ 짧은 ꡬ간은 [1, 3], [2, 4]κ°€ μžˆμŠ΅λ‹ˆλ‹€.
μ‹œμž‘ μ§„μ—΄λŒ€ λ²ˆν˜Έκ°€ 더 μž‘μ€ [1, 3]을 return ν•΄μ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€.

 

μž…μΆœλ ₯ 예 #3
1μ’…λ₯˜μ˜ 보석(XYZ)을 ν¬ν•¨ν•˜λŠ” κ°€μž₯ 짧은 ꡬ간은 [1, 1], [2, 2], [3, 3]이 μžˆμŠ΅λ‹ˆλ‹€.
μ‹œμž‘ μ§„μ—΄λŒ€ λ²ˆν˜Έκ°€ κ°€μž₯ μž‘μ€ [1, 1]을 return ν•΄μ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€.

 

μž…μΆœλ ₯ 예 #4
4μ’…λ₯˜μ˜ 보석(ZZZ, YYY, NNNN, BBB)을 λͺ¨λ‘ ν¬ν•¨ν•˜λŠ” ꡬ간은 [1, 5]κ°€ μœ μΌν•©λ‹ˆλ‹€.
κ·ΈλŸ¬λ―€λ‘œ [1, 5]λ₯Ό return ν•΄μ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€.


 

🏝 풀이 μ½”λ“œ

from collections import Counter

def solution(gems):
    num = len(set(gems))
    result = []

    left = 0
    counter = Counter()
        
    for right in range(len(gems)):
        counter[gems[right]] += 1
        right += 1
        while len(counter) == num:
            counter[gems[left]] -= 1
            if counter[gems[left]] == 0:
                del counter[gems[left]]
            left += 1
            result.append([left, right])
            
    return sorted(result, key = lambda x: (x[1]-x[0], x[0]))[0]

 

투 포인터 λ¬Έμ œμ˜€λ‹€.

 

μš°μ„  λ“€μ–΄μžˆλŠ” 보석을 Counter에 μ €μž₯ν•  것이닀. Counter의 λ“€μ–΄μžˆλŠ” ν‚€μ˜ 개수둜 λ‚΄κ°€ κ΅¬λ§€ν•˜λ €λŠ” λ³΄μ„μ˜ μ’…λ₯˜μ˜ 개수λ₯Ό νŒλ‹¨ν•  수 μžˆλ‹€.

 

μ™Όμͺ½ ν¬μΈν„°λŠ” 0에 두고, for문을 ν†΅ν•΄μ„œ rightλ₯Ό κ³„μ†ν•΄μ„œ μ΄λ™ν•œλ‹€.

right += 1은 indexκ°€ μ•„λ‹Œ index+1 값을 리턴해야 ν•˜λ―€λ‘œ whileλ¬Έ 전에 미리 ν•΄λ‘” 것이닀.

μ™Όμͺ½ ν¬μΈν„°λŠ” 0으둜 κ³ μ •ν•œ ν›„, λͺ¨λ“  보석을 ꡬ맀할 수 μžˆμ„ λ•ŒκΉŒμ§€ rightλ₯Ό λŠ˜λ¦°λ‹€. (for문으둜 λŠ˜λ¦¬λŠ” 것)

κ·Έ 이후에 μ™Όμͺ½ ν¬μΈν„°μ˜ 보석을 ν•˜λ‚˜ μΉ΄μš΄ν„°μ—μ„œ μ œκ±°ν•˜κ³ , κ°―μˆ˜κ°€ 0이 λœλ‹€λ©΄ μ•„μ˜ˆ μ’…λ₯˜ μ—­μ‹œ μΉ΄μš΄ν„°μ—μ„œ μ œν•œλ‹€.

κ·Έ ν›„ leftλ₯Ό ν•œ μΉΈ 이동(index + 1 ν‘œν˜„λ„ λ™μ‹œμ—)ν•˜λŠ”λ°, 이것을 μ™Όμͺ½ 포인터가 이동해도 μΉ΄μš΄ν„° λ‚΄μ˜ 보석 μ’…λ₯˜μ˜ 수 λ³€ν™”κ°€ 없을 λ•ŒκΉŒμ§€ λ°˜λ³΅ν•œλ‹€.

 

이 후에도 더 짧은 λ²”μœ„κ°€ μ‘΄μž¬ν•  수 μžˆμœΌλ―€λ‘œ, κ³„μ†ν•΄μ„œ right에 λŒ€ν•œ for문을 μ§„ν–‰ν•œλ‹€.

 

될 수 μžˆλŠ” 후보가 μ €μž₯된 result 배열에 λŒ€ν•΄ λ²”μœ„ κ°’(x[1]-x[0])으둜 μš°μ„  μ •λ ¬ν•˜κ³ , κ·Έ ν›„ μ•žμ— κ°€κΉŒμš΄ λ²”μœ„λ₯Ό κ·Έ λ‹€μŒ μ •λ ¬ν•œλ‹€.

κ°€μž₯ μ•žμ˜ 값을 λ¦¬ν„΄ν•˜λ©΄ 정닡이닀.

 

투 포인터 λ¬Έμ œμ΄μ§€λ§Œ, left λ¨Όμ € μ΄λ™ν•˜κ³ , right λ‹€μŒ μ΄λ™μ‹œν‚€λŠ” λ¬Έμ œλ“€λ³΄λ‹€λŠ” μƒκ°ν•˜λŠ”λ° 어렀움이 μžˆλ‹€.

μ΅μˆ™ν•΄μ§€λ©΄ λ‹€λ₯Έ 문제 ν’€ λ•Œμ—λ„ μœ μš©ν•  것 κ°™λ‹€. μˆ™μ§€ν•΄λ‘μž.