Algorithm

[Algorithm] N으둜 ν‘œν˜„ (깊이 μš°μ„  탐색(DFS))

_보름 2021. 3. 19. 17:35

πŸ–₯ 문제

μ•„λž˜μ™€ 같이 5와 μ‚¬μΉ™μ—°μ‚°λ§ŒμœΌλ‘œ 12λ₯Ό ν‘œν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
12 = 5 + 5 + (5 / 5) + (5 / 5)
12 = 55 / 5 + 5 / 5
12 = (55 + 5) / 5
5λ₯Ό μ‚¬μš©ν•œ νšŸμˆ˜λŠ” 각각 6,5,4μž…λ‹ˆλ‹€. 그리고 이쀑 κ°€μž₯ μž‘μ€ κ²½μš°λŠ” 4μž…λ‹ˆλ‹€.
이처럼 숫자 Nκ³Ό numberκ°€ μ£Όμ–΄μ§ˆ λ•Œ, Nκ³Ό μ‚¬μΉ™μ—°μ‚°λ§Œ μ‚¬μš©ν•΄μ„œ ν‘œν˜„ν•  수 μžˆλŠ” 방법 쀑 N μ‚¬μš© 횟수의 μ΅œμ†Ÿκ°’μ„ return ν•˜λ„λ‘ solution ν•¨μˆ˜λ₯Ό μž‘μ„±ν•˜μ„Έμš”.

πŸ€” 풀이 방법

By Mre - Own work, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=6342841

이 λ¬Έμ œλŠ” λ™μ κ³„νšλ²•(Dynamic Programming)으둜 λΆ„λ₯˜λ˜μ–΄ μžˆμ§€λ§Œ, 깊이 μš°μ„  탐색(Depth-First Search)으둜 ν’€μ—ˆλ‹€.
깊이 μš°μ„  νƒμƒ‰μ΄λž€ λ£¨νŠΈλ…Έλ“œμ—μ„œ λΆ€ν„° μ‹œμž‘ν•΄μ„œ λ‹€μŒ 브랜치둜 λ„˜μ–΄κ°€κΈ° 전에 ν•΄λ‹Ή 브랜치λ₯Ό μ™„λ²½ν•˜κ²Œ νƒμƒ‰ν•˜λŠ” 방법이닀.

  1. λ³€μˆ˜
    • countN : N이 μ‚¬μš©λœ 개수
    • resultN : N을 μ΄μš©ν•˜μ—¬ κ³„μ‚°ν•œ μ‹μ˜ κ²°κ³Ό
    • calN : n ~ nnnnnnnn의 수
  2. if countN > 8 { return }
    • N은 1이상 9 μ΄ν•˜μ΄λ‹€. 8을 μ΄ˆκ³Όν•˜λ©΄(0 ~ 8κΉŒμ§€ 총 9개λ₯Ό μ΄ˆκ³Όν•˜λ©΄) 리턴해쀀닀. μ΄λ•Œ κ²°κ³ΌλŠ” -1이 λœλ‹€.
  3. if bumber == resultN : number와 κ³„μ‚°ν•œ μ‹μ˜ κ²°κ³Ό resultN이 같을 경우
    • result == -1 : 아직 κ³„μ‚°λœ κ²°κ³Όκ°€ μ—†μ–΄ 처음으둜 resultλ₯Ό μ—…λ°μ΄νŠΈ ν•΄μ€˜μ•Ό ν•˜λŠ” 경우
    • countN < result : ν˜„μž¬ result의 κ°’ 보닀 더 적은 개수의 N을 μ‚¬μš©ν•œ 경우
    • μœ„ λ‘κ°œμ˜ κ²½μš°μ— resultλ₯Ό N이 μ‚¬μš©λœ 개수 countN으둜 μ—…λ°μ΄νŠΈ ν•΄μ£Όκ³  λ¦¬ν„΄ν•œλ‹€.
  4. calN에 n ~ nnnnnnnn의 수λ₯Ό ν•˜λ‚˜μ”© λ„£μ–΄μ£Όλ©° νƒμƒ‰ν•œλ‹€.
    for i in 0..<8 { 
     calN = calN * 10 + N
     ...
    }
  5. dfs(N, number, countN + 1 + i, resultN + calN, &result) : resultN에 λŒ€ν•˜μ—¬ calN을 +, -, *, / 연산을 μˆ˜ν–‰ν•œλ‹€.
    • countN + 1 + i : countN에 N이 μ‚¬μš©λœ 개수λ₯Ό λ„˜κ²¨μ€€λ‹€.
    • resultN + calN : resultN에 κ³„μ‚°ν•œ μ‹μ˜ κ²°κ³Όλ₯Ό λ„˜κ²¨μ€€λ‹€.

πŸ‘©πŸ»‍πŸ’» Swift Code

import Foundation

func solution(_ N:Int, _ number:Int) -> Int {
    var result: Int = -1
    dfs(N, number, 0, 0, &result)
    return result
}

func dfs(_ N:Int, _ number:Int, _ countN:Int, _ resultN:Int, _ result: inout Int) {
    var calN = 0

    if countN > 8 {
        return
    }

    if number == resultN && (result == -1 || countN < result) {
        result = countN
        return
    }

    for i in 0..<8 {
        calN = calN * 10 + N
        dfs(N, number, countN + 1 + i, resultN + calN, &result)
        dfs(N, number, countN + 1 + i, resultN - calN, &result)
        dfs(N, number, countN + 1 + i, resultN * calN, &result)
        dfs(N, number, countN + 1 + i, resultN / calN, &result)
    }
}

 

 

μ½”λ”©ν…ŒμŠ€νŠΈ μ—°μŠ΅ - N으둜 ν‘œν˜„

 

programmers.co.kr