πŸ“– Problem Solution/Programmers

[Swift] 2020 KAKAO BLIND RECRUITMENT 가사 검색

Fomagran πŸ’» 2022. 1. 3. 19:34
728x90
λ°˜μ‘ν˜•



Problem

 

 

μ½”λ”©ν…ŒμŠ€νŠΈ μ—°μŠ΅ - 가사 검색

 

programmers.co.kr


Solution

 

ν•΄λ‹Ή λ¬Έμ œλŠ” Trie 자료ꡬ쑰λ₯Ό μ‚¬μš©ν•΄μ„œ ν’€μ–΄μ•Ό ν•˜λŠ” λ¬Έμ œμž…λ‹ˆλ‹€.

 

(Trie κ΄€λ ¨ν•΄μ„œλŠ” λ”°λ‘œ μ •λ¦¬ν•΄μ„œ μ˜¬λ¦¬λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€!γ…œ)

 

1. Trie 자료 ꡬ쑰λ₯Ό λ§Œλ“€μ–΄μ€€λ‹€.

 

μ •μ„μœΌλ‘œ λ§Œλ“ κ±΄ μ•„λ‹ˆκ³  κ°„λ‹¨ν•˜κ²Œ 단어λ₯Ό Trie μžλ£Œκ΅¬μ‘°μ— 맞게 μ‚½μž…ν•˜λŠ” insert λ©”μ„œλ“œμ™€

 

κΈ€μžμ˜ μžμ‹μ΄ λͺ‡ 개 μžˆλŠ”μ§€ μ„Έμ–΄μ£ΌλŠ” getCount λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν–ˆμŠ΅λ‹ˆλ‹€.

 

class Node {
    var value:String
    var count:Int = 0
    var children:[String:Node] = [:]
    init(value:String) {
        self.value = value
    }
    func append(_ value:String) {
        self.children[value] = Node(value: value)
    }
}

class Trie {
    let root:Node = Node(value:"")
    
    func insert(_ word:String) {
        var current = root
        let map = word.map{String($0)}
        map.forEach {
            current.count += 1
            if !current.children.keys.contains($0) {
                current.append($0)
            }
            current = current.children[$0]!
        }
    }
    
    func getCount(_ word:String) -> Int {
        var current = root
        let map = word.map{String($0)}
        for w in map {
            if !current.children.keys.contains(w) {
                return 0
            }
            current = current.children[w]!
        }
        return current.count == 0 ? 1 : current.count
    }
}

 

2. μ˜¬λ°”λ₯Έ Trie와 뒀집어진 κΈ€μžλ₯Ό 담을 Trieλ₯Ό λ§Œλ“€μ–΄μ€€λ‹€.

 

κΈ€μžλ‘œ μ‹œμž‘ν•˜λŠ” λ‹¨μ–΄λŠ” μ˜¬λ°”λ₯Έ trie둜, ?둜 μ‹œμž‘ν•˜λŠ” λ‹¨μ–΄λŠ” 뒀집어진 trie인 reverse둜 λ”°λ‘œ κ΄€λ¦¬ν•΄μ€λ‹ˆλ‹€.

 

struct Tries {
    var trie:Trie,reverse:Trie
}

 

3. 단어 κ°―μˆ˜μ— 맞게 λΆ„λ₯˜ν•΄μ€€λ‹€.

 

func classifyByWordLength(_ words:[String]) -> [Int:Tries] {
    var lengthDic:[Int:Tries] = [:]
    for word in words {
        if lengthDic[word.count] == nil {
            let tries = Tries(trie: Trie(), reverse: Trie())
            tries.trie.insert(word)
            tries.reverse.insert(String(word.reversed()))
            lengthDic[word.count] = tries
        }else {
            lengthDic[word.count]!.trie.insert(word)
            lengthDic[word.count]!.reverse.insert(String(word.reversed()))
        }
    }
    return lengthDic
}

 

4. 쿼리에 맞게 갯수λ₯Ό λ‹΄μ•„μ€€λ‹€.

 

μ£Όμ˜ν•  점은 query μ•ˆμ˜ λ‹¨μ–΄μ˜ 길이가 lengthDic에 μ—†λ‹€λ©΄ 0을 λ°˜ν™˜ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

 

func queriesResults(_ queries:[String],_ lengthDic:[Int:Tries]) -> [Int] {
    var results:[Int] = []
    for query in queries {
        let count = query.count
        if lengthDic[count] == nil {
            results.append(0)
            continue
        }
        var pre = query.map{String($0)}.filter{$0 != "?"}.joined()
        pre = query.first == "?" ? String(pre.reversed()) : pre
        let trie = query.first == "?" ? lengthDic[count]!.reverse : lengthDic[count]!.trie
        let result = trie.getCount(pre)
        results.append(result)
    }
    return results
}

 

5. resultsλ₯Ό λ°˜ν™˜ν•œλ‹€.

 

func solution(_ words:[String], _ queries:[String]) -> [Int] {
    let lengthDic:[Int:Tries] = classifyByWordLength(words)
    return queriesResults(queries,lengthDic)
}

Source Code

 

728x90
λ°˜μ‘ν˜•