Algorithm/Programmers

[ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€] (Swift) Kakao - 후보킀 (Lv.2)

감자 πŸ₯” 2022. 8. 31. 18:00
λ°˜μ‘ν˜•

🟠 문제 링크

https://school.programmers.co.kr/learn/courses/30/lessons/42890

 

ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€

μ½”λ“œ μ€‘μ‹¬μ˜ 개발자 μ±„μš©. μŠ€νƒ 기반의 ν¬μ§€μ…˜ λ§€μΉ­. ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€μ˜ 개발자 λ§žμΆ€ν˜• ν”„λ‘œν•„μ„ λ“±λ‘ν•˜κ³ , λ‚˜μ™€ 기술 ꢁ합이 잘 λ§žλŠ” 기업듀을 λ§€μΉ­ λ°›μœΌμ„Έμš”.

programmers.co.kr

 

🟠 λ‚˜μ˜ 풀이

후보킀가 될 수 μžˆλŠ” 쑰합을 μƒκ°ν•΄μ•Όν–ˆλ‹€. κ·Έλž˜μ„œ combination ν•¨μˆ˜λ₯Ό μ‚¬μš©ν–ˆλ‹€. 

//nκ°œμ€‘ mλ₯Ό μˆœμ„œμ— 상관없이 뽑아야할 쑰합듀을 λ§Œλ“€μ–΄μ£ΌλŠ” ν•¨μˆ˜
func combination(n: [Int], m: Int, current index: Int, pickedArray: [Int]) {
    if m == 0 {
        cases.append(pickedArray)
    }else if index == n.count {
        return
    }else {
        var newSelected = pickedArray
        newSelected.append(n[index])
        combination(n: n, m: m-1, current: index+1, pickedArray: newSelected)
        combination(n: n, m: m, current: index+1, pickedArray: pickedArray)
    }
}

이 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ μ•„λž˜μ™€ 같은 κ²°κ³Όλ₯Ό 얻을 수 μžˆλ‹€.

// μ‚¬μš©λ²•
var temp = [1, 2, 3, 4, 5]
for i in 0..<temp.count {
    combination(n: temp, m: i+1, current: 0, pickedArray: [])
}
print(cases)

μ΄λ ‡κ²Œ λͺ¨λ“  ν›„λ³΄ν‚€λ“€μ˜ 쑰합을 얻을 수 μžˆλ‹€.

 

μ΄λ ‡κ²Œ κ΅¬ν•˜κ²Œ 되면, ν•΄λ‹Ή 후보킀에 ν•΄λ‹Ήν•˜λŠ” value듀을 λ„£κ³ , valueλ“€μ˜ λͺ¨μŒμ˜ 길이가 relation 길이와 κ°™λ‹€λ©΄ μ‘°κ±΄μ—μ„œ μ£Όμ–΄μ§„ 'μœ μΌμ„±'을 λ§Œμ‘±ν•˜λŠ” 것이닀. (μ•„λž˜ 사진)

이제 μ‘°κ±΄μ—μ„œ μ£Όμ–΄μ§„, μ΅œμ†Œμ„±μ„ λ§Œμ‘±ν•˜λŠ”κ°€λ₯Ό λ΄μ•Όν•˜λŠ”λ°, 이뢀뢄이 살짝 이해가 κ°€μ§ˆ μ•Šμ•˜λ‹€. μœ„ 사진 μ˜ˆμ‹œλ‘œ 보면 [ν•™λ²ˆ, 이름] 이 이미 ν›„λ³΄ν‚€μ˜ 뢀뢄집합에 ν•΄λ‹Ήν•œλ‹€λ©΄, μ΅œμ†Œμ„±μ„ λ§Œμ‘±ν•˜μ§€ λͺ»ν•˜λŠ” κ²ƒμœΌλ‘œ κ°„μ£Όν•œλ‹€.  (μ•„λž˜ μ„€λͺ…)

🟠 μ •λ‹΅ μ½”λ“œ

https://github.com/deslog/Algorithm/blob/main/Algorithm/Programmers/kakao_%ED%9B%84%EB%B3%B4%ED%82%A4/main.swift

 

GitHub - deslog/Algorithm

Contribute to deslog/Algorithm development by creating an account on GitHub.

github.com

import Foundation

//쑰합듀을 담을 λ°°μ—΄
var cases = [[Int]]()

func solution(_ relation:[[String]]) -> Int {
    var candidateKey = [[Int]]()
    var colsize = [Int]()

    for i in 0..<relation[0].count {
        colsize.append(i)
    }
    // μ»¬λŸΌμˆ˜λ“€μ˜ μ‘°ν•© 생성
    for i in 0..<colsize.count {
        combination(n: colsize, m: i+1, current: 0, pickedArray: [])
    }

    // μ΅œμ†Œμ„± 확인 isSuperset() 뢀뢄집합인지 확인
    out: for c in cases {
    //μ΅œμ†Œμ„±μ„ λ§Œμ‘±ν•˜λŠ”μ§€ 확인
        let set = Set(c)
        //후보킀듀을 탐색
        for key in candidateKey {
            //후보킀 μ•ˆμ— ν˜„μž¬ keyκ°€ ν¬ν•¨λœκ²Œ μžˆλ‹€λ©΄ λ„˜μ–΄κ°„λ‹€.
            if set.isSuperset(of: key) {
                continue out
            }
        }

        var rowSet = Set<Array<String>>()
        // rowλ³„λ‘œ combi에 μžˆλŠ” μ†μ„±λ“€λ§Œ λ½‘μ•„μ„œ 확인
        for row in relation {
            var tuple = [String]()

            for i in c {
                tuple.append(row[i])
            }

            if !rowSet.contains(tuple) {
                rowSet.insert(tuple)
            } else {
                break
            }
        }

        if rowSet.count == relation.count {
            candidateKey.append(c)
        }
    }

    return candidateKey.count
}

//nκ°œμ€‘ mλ₯Ό μˆœμ„œμ— 상관없이 뽑아야할 쑰합듀을 λ§Œλ“€μ–΄μ£ΌλŠ” ν•¨μˆ˜
func combination(n: [Int], m: Int, current index: Int, pickedArray: [Int]) {
    if m == 0 {
        cases.append(pickedArray)
    }else if index == n.count {
        return
    }else {
        var newSelected = pickedArray
        newSelected.append(n[index])
        combination(n: n, m: m-1, current: index+1, pickedArray: newSelected)
        combination(n: n, m: m, current: index+1, pickedArray: pickedArray)
    }
}

 

λ°˜μ‘ν˜•