Daily Coding Problem: Problem #949

复制代码
/**
 * This problem was asked by Twitter.
Implement an autocomplete system.
That is, given a query string s and a set of all possible query strings, return all strings in the set that have s as a prefix.
For example, given the query string de and the set of strings [dog, deer, deal], return [deer, deal].
Hint: Try preprocessing the dictionary into a more efficient data structure to speed up queries.
 * */
class Problem_949 {

    /*
    * solution: DFS and Trie Tree(prefix tree), add all word into prefix tree for searching;
    * Time and Space complexity are: O(2^L), L is the length of key word
    * */

    private var root: TrieNode? = null

    init {
        root = TrieNode()
    }

    fun getSamePrefix(query: String, strings: ArrayList<String>): ArrayList<String> {
        val result = ArrayList<String>()
        for (word in strings) {
            root?.insert(word)
        }
        var lastNode = root
        val sb = StringBuilder()
        //find out the last node for start dfs
        for (c in query) {
            lastNode = lastNode?.children?.get(c)
            if (lastNode != null) {
                sb.append(c)
            }
        }
        dfs(lastNode, result, sb)
        return result
    }

    private fun dfs(node: TrieNode?, list: ArrayList<String>, cur: StringBuilder) {
        if (node?.isWord!!) {
            list.add(cur.toString())
        }
        if (node.children.isEmpty()) {
            return
        }
        for (child in node.children.values) {
            dfs(child, list, cur.append(child.char.toString()))
            //reduce the length for backtracking
            cur.setLength(cur.length - 1)
        }
    }

    /**
     * node for TrieTree
     * */
    class TrieNode constructor(c: Char?) {
        var isWord = false
        var char: Char? = null
        val children = HashMap<Char, TrieNode>()

        constructor() : this(null)

        init {
            char = c
        }

        fun insert(word: String?) {
            if (word == null || word.isEmpty()) {
                return
            }
            val first = word[0]
            var child = children.get(first)
            if (child == null) {
                child = TrieNode(first)
                children.put(first, child)
            }
            //insert entire word
            if (word.length > 1) {
                child.insert(word.substring(1))
            } else {
                child.isWord = true
            }
        }
    }
}
复制代码

 

posted @   johnny_zhao  阅读(38)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示