๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“– Problem Solution/Programmers

[Swift] 2020 KAKAO BLIND RECRUITMENT ๊ฐ€์‚ฌ ๊ฒ€์ƒ‰

by Fomagran ๐Ÿ’ป 2022. 1. 3.
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
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€