λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
3️⃣ Swift/Problem Solving

[Swift Algorithm] 체윑볡 Programmers(Lv.1)

by seolhee2750 2021. 6. 18.
문제 μ„€λͺ…

μ μ‹¬μ‹œκ°„μ— 도둑이 λ“€μ–΄, 일뢀 학생이 μ²΄μœ‘λ³΅μ„ λ„λ‚œλ‹Ήν–ˆμŠ΅λ‹ˆλ‹€. λ‹€ν–‰νžˆ μ—¬λ²Œ 체윑볡이 μžˆλŠ” 학생이 μ΄λ“€μ—κ²Œ μ²΄μœ‘λ³΅μ„ 빌렀주렀 ν•©λ‹ˆλ‹€. ν•™μƒλ“€μ˜ λ²ˆν˜ΈλŠ” 체격 순으둜 맀겨져 μžˆμ–΄, λ°”λ‘œ μ•žλ²ˆν˜Έμ˜ ν•™μƒμ΄λ‚˜ λ°”λ‘œ λ’·λ²ˆν˜Έμ˜ ν•™μƒμ—κ²Œλ§Œ μ²΄μœ‘λ³΅μ„ λΉŒλ €μ€„ 수 μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, 4번 학생은 3번 ν•™μƒμ΄λ‚˜ 5번 ν•™μƒμ—κ²Œλ§Œ μ²΄μœ‘λ³΅μ„ λΉŒλ €μ€„ 수 μžˆμŠ΅λ‹ˆλ‹€. 체윑볡이 μ—†μœΌλ©΄ μˆ˜μ—…μ„ 듀을 수 μ—†κΈ° λ•Œλ¬Έμ— μ²΄μœ‘λ³΅μ„ 적절히 빌렀 μ΅œλŒ€ν•œ λ§Žμ€ 학생이 μ²΄μœ‘μˆ˜μ—…μ„ λ“€μ–΄μ•Ό ν•©λ‹ˆλ‹€.

전체 ν•™μƒμ˜ 수 n, μ²΄μœ‘λ³΅μ„ λ„λ‚œλ‹Ήν•œ ν•™μƒλ“€μ˜ λ²ˆν˜Έκ°€ λ‹΄κΈ΄ λ°°μ—΄ lost, μ—¬λ²Œμ˜ μ²΄μœ‘λ³΅μ„ κ°€μ Έμ˜¨ ν•™μƒλ“€μ˜ λ²ˆν˜Έκ°€ λ‹΄κΈ΄ λ°°μ—΄ reserveκ°€ λ§€κ°œλ³€μˆ˜λ‘œ μ£Όμ–΄μ§ˆ λ•Œ, μ²΄μœ‘μˆ˜μ—…μ„ 듀을 수 μžˆλŠ” ν•™μƒμ˜ μ΅œλŒ“κ°’μ„ return ν•˜λ„λ‘ solution ν•¨μˆ˜λ₯Ό μž‘μ„±ν•΄μ£Όμ„Έμš”.

 

μ œν•œ 쑰건
  • 전체 ν•™μƒμ˜ μˆ˜λŠ” 2λͺ… 이상 30λͺ… μ΄ν•˜μž…λ‹ˆλ‹€.
  • μ²΄μœ‘λ³΅μ„ λ„λ‚œλ‹Ήν•œ ν•™μƒμ˜ μˆ˜λŠ” 1λͺ… 이상 nλͺ… μ΄ν•˜μ΄κ³  μ€‘λ³΅λ˜λŠ” λ²ˆν˜ΈλŠ” μ—†μŠ΅λ‹ˆλ‹€.
  • μ—¬λ²Œμ˜ μ²΄μœ‘λ³΅μ„ κ°€μ Έμ˜¨ ν•™μƒμ˜ μˆ˜λŠ” 1λͺ… 이상 nλͺ… μ΄ν•˜μ΄κ³  μ€‘λ³΅λ˜λŠ” λ²ˆν˜ΈλŠ” μ—†μŠ΅λ‹ˆλ‹€.
  • μ—¬λ²Œ 체윑볡이 μžˆλŠ” ν•™μƒλ§Œ λ‹€λ₯Έ ν•™μƒμ—κ²Œ μ²΄μœ‘λ³΅μ„ λΉŒλ €μ€„ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ—¬λ²Œ μ²΄μœ‘λ³΅μ„ κ°€μ Έμ˜¨ 학생이 μ²΄μœ‘λ³΅μ„ λ„λ‚œλ‹Ήν–ˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λ•Œ 이 학생은 μ²΄μœ‘λ³΅μ„ ν•˜λ‚˜λ§Œ λ„λ‚œλ‹Ήν–ˆλ‹€κ³  κ°€μ •ν•˜λ©°, 남은 체윑볡이 ν•˜λ‚˜μ΄κΈ°μ— λ‹€λ₯Έ ν•™μƒμ—κ²ŒλŠ” μ²΄μœ‘λ³΅μ„ λΉŒλ €μ€„ 수 μ—†μŠ΅λ‹ˆλ‹€.

 

μž…μΆœλ ₯ 예
n lost reserve return
5 [2, 4] [1, 3, 5] 5
5 [2, 4] [3] 4
3 [3] [1] 2

 

λ‚΄ 문제 풀이
import Foundation

func solution(_ n:Int, _ lost:[Int], _ reserve:[Int]) -> Int {
    var student = Array<Int>(repeating: 1, count: n)
    var result = 0
    
    for i in 0..<lost.count {
        student[lost[i]-1] -= 1
    }
    for i in 0..<reserve.count {
        student[reserve[i]-1] += 1
    }

    if student[0] == 0 && student[1] == 2 {
        student[0] = 1
        student[1] = 1
    }
    if student[n-1] == 0 && student[n-2] == 2 {
        student[n-1] = 1
        student[n-2] = 1
    }
    
    if n > 2 {
        for i in 1..<n-1 {
            if student[i] == 0 {
                if student[i-1] == 2 {
                    student[i] = 1
                    student[i-1] = 1
                }
                else {
                    if student[i+1] == 2 {
                        student[i] = 1
                        student[i+1] = 1
                    }
                }
            }
        }
    }
    
    for i in 0..<n {
        if student[i] == 0 {
            result += 1
        }
    }
    
    return n - result
}
  • λ¨Όμ € 학생 수 크기의 배열을 μƒμ„±ν•˜κ³ , 1μ”© μ €μž₯ν•΄μ£Όμ—ˆλ‹€.
  • κ·Έ λ‹€μŒ μ²΄μœ‘λ³΅μ„ μžƒμ–΄λ²„λ¦° 학생은 -1, 여뢄이 μžˆλŠ” 학생은 +1 ν•΄μ£Όμ—ˆλ‹€. (맨 μœ„ forλ¬Έ 두 개)
  • 그리고 이제 μ²΄μœ‘λ³΅μ„ λΆ„λ°°ν•  차둀인데, μš°μ„  맨 μ•ž 학생과 맨 λ’€ ν•™μƒλ§Œ μ˜ˆμ™Έλ‘œ μ²˜λ¦¬ν•΄μ£Όμ—ˆλ‹€.
    (맨 첫 번째 학생이 체윑볡이 μ—†κ³ , κ·Έ λ‹€μŒ 학생이 μ—¬λ²Œμ΄ μžˆμ„ 경우,
    그리고 맨 λ’€ 학생이 체윑볡이 μ—†κ³ , κ·Έ μ „ 학생이 μ—¬λ²Œμ΄ μžˆμ„ 경우!)
  • 그리고 학생 μˆ˜κ°€ 3λͺ… 이상일 경우 for문으둜 μ²΄μœ‘λ³΅μ„ λ°°λΆ„ν–ˆλ‹€.
    (2λͺ… μ΄ν•˜μΌ 경우 μœ„μ˜ μ˜ˆμ™Έ μ²˜λ¦¬λ“€λ‘œ λΆ„λ°° κ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έ!)
  • for문은 λ°°μ—΄μ˜ 1λΆ€ν„° n-2κΉŒμ§€ λ°˜λ³΅ν•΄μ£Όμ—ˆλ‹€. (0, n-1은 μœ„μ—μ„œ μ²˜λ¦¬ν–ˆκΈ° λ•Œλ¬Έ)
  • forλ¬Έ μ•ˆμ—μ„œλŠ” λ§Œμ•½ student λ°°μ—΄μ˜ i 번째 학생이 0일 경우 μ•ž, λ’€ 학생이 μ—¬λ²Œμ„ κ°–λŠ”μ§€ ν™•μΈν–ˆλ‹€.
  • λ¨Όμ € μ•ž 학생이 μ—¬λ²Œμ΄ μžˆλ‹€λ©΄ (2 라면) κ·Έ ν•™μƒμ—κ²Œ 빌리고, μ•ž 학생이 μ—¬λ²Œμ΄ μ—†κ³  λ’€ 학생이 μžˆλ‹€λ©΄ λΉŒλ €μ£Όμ—ˆλ‹€.
  • μœ„μ™€ 같은 λ°©μ‹μœΌλ‘œ μ§„ν–‰ν•œ ν›„, for문을 μ΄μš©ν•΄ 배뢄이 λλ‚¬μŒμ—λ„ 체윑볡이 μ—†λŠ” 학생 수λ₯Ό κ΅¬ν–ˆλ‹€.
  • 전체 학생 μˆ˜μ—μ„œ 체윑볡이 μ—†λŠ” 학생 수λ₯Ό λΉΌμ£Όμ–΄ λ°˜ν™˜ν–ˆλ‹€.

 

인상적인 풀이
import Foundation

func solution(_ n: Int, _ lost: [Int], _ reserve: [Int]) -> Int {
    let newReserve = reserve.filter { !lost.contains($0) }
    let newLost = lost.filter { !reserve.contains($0) }

    var lostPeople: Int = newLost.count

    newReserve.forEach {
        let isLend: Bool = newLost.contains($0 - 1) || newLost.contains($0 + 1)
        if isLend && lostPeople > 0 {
            lostPeople -= 1
        }
    }

    return n - lostPeople
}
  • λ¨Όμ € filterλ₯Ό μ‚¬μš©ν•˜μ—¬ μ—¬λ²Œμ΄ μžˆλŠ” 학생 쀑 λ„λ‚œ λ‹Ήν•˜μ§€ μ•Šμ€ ν•™μƒλ“€λ‘œ newReserve 배열을 생성, 
    λ„λ‚œλ‹Ήν•œ 학생듀 쀑 μ—¬λ²Œμ΄ μ—†λŠ” ν•™μƒλ“€λ‘œ newLost 배열을 μƒμ„±ν•΄μ£Όμ—ˆλ‹€.
  • μ—¬λ²Œ 없이 μžƒμ–΄λ²„λ¦° ν•™μƒλ“€μ˜ λͺ…μˆ˜λ₯Ό lostPeople에 μ €μž₯ν–ˆλ‹€.
  • newReserve에 forEachλ₯Ό μ‚¬μš©ν•΄ λ°˜λ³΅ν•΄μ£Όμ—ˆκ³ ,
    newReserve의 ν•™μƒμ˜ μ•ž, λ’€ 학생이 newLost 배열에 ν¬ν•¨λ˜λŠ” 학생인지 κ²€μ‚¬ν•œλ‹€.
  • λ§Œμ•½ 검사 κ²°κ³Όκ°€ trueμ΄λ©΄μ„œ 체윑볡이 μ—†λŠ” 학생이 1λͺ… 이상일 경우 lostPeopleμ—μ„œ ν•œ λͺ…을 λΉΌμ£ΌλŠ” 것을 λ°˜λ³΅ν•œλ‹€.
  • λ§ˆμ§€λ§‰μœΌλ‘œ 전체 학생 μˆ˜μ—μ„œ 체윑볡이 μ—†λŠ” 학생 수λ₯Ό λΉΌμ£Όμ–΄ λ°˜ν™˜ν–ˆλ‹€.

 

πŸ’‘ ν”Όλ“œλ°±
  • filter와 containsλ₯Ό 적절히 μ‚¬μš©ν•˜μ—¬ 정말 효과적인 μ½”λ“œλ₯Ό μž‘μ„±ν•œ 것,, λ„ˆλ¬΄ λŒ€λ‹¨ν•˜λ‹€
  • λ‚˜λ„ λ‹€μ–‘ν•œ ν•¨μˆ˜λ₯Ό 많이 μ‚¬μš©ν•΄λ³΄λ©° λ”μš± κ°„κ²°ν•˜κ²Œ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ„λ‘ μ—°μŠ΅ν•΄μ•Όκ² λ‹€,,

 


 

πŸ– [ μΆ”κ°€ ] 1주일 ν›„ λ‹€μ‹œ 풀어보기

func solution2(_ n:Int, _ lost:[Int], _ reserve:[Int]) -> Int {
    var stu = Array(repeating: 1, count: n)
    for i in 0..<lost.count { stu[lost[i]-1] -= 1 }
    for i in 0..<reserve.count { stu[reserve[i]-1] += 1 }
                             
    if stu[0]==0 && stu[1]==2 { stu[0]=1; stu[1]=1 }
    if stu[n-1]==0 && stu[n-2]==2 {stu[n-1]=1; stu[n-2]=1}

    for i in 1..<n-1 {
        if stu[i]==0 {
            if stu[i-1]==2 { stu[i-1]=1; stu[i]=1 }
            else if stu[i+1]==2 { stu[i]=1; stu[i+1]=1 }
        }
    }
    
    return stu.filter({$0 > 0}).count
}
  • 학생 수만큼 1을 μ±„μš΄ 배열을 λ§Œλ“€μ–΄μ€€ ν›„ μžƒμ–΄λ²„λ¦° 학생은 -1, 여뢄이 μžˆλŠ” 학생은 +1 ν•΄μ£Όμ—ˆλ‹€.
  • 첫 번째 학생이 체윑볡이 μ—†λŠ” 상황과 λ§ˆμ§€λ§‰ 학생이 체윑볡이 μ—†λŠ” 상황은 λ”°λ‘œ λΉΌμ„œ ν•΄κ²°ν–ˆλ‹€.
  • forλ¬Έμ—μ„œλŠ” [1]번째 학생뢀터, 체윑볡이 μ—†λ‹€λ©΄ 이전 ν•™μƒμ—κ²Œ μš°μ„ , μ•ˆλ˜λ©΄ λ’€ ν•™μƒμ—κ²Œ λΉŒλ¦¬λŠ” μ‹μœΌλ‘œ μž‘μ„±ν–ˆλ‹€.
  • filter μ‚¬μš©ν•˜μ—¬ μ²΄μœ‘λ³΅μ„ ν•œ 개 이상 κ°€μ§€κ²Œ 된 ν•™μƒλ“€μ˜ 수λ₯Ό 좜λ ₯ν–ˆλ‹€.
  • 첫 번째 풀이보닀 훨씬 κ°„κ²°ν•˜κ²Œ 잘 μž‘μ„±ν•œλ“― ν•˜λ‹€!!

 


 

문제

https://programmers.co.kr/learn/courses/30/lessons/42862

λŒ“κΈ€