zoukankan      html  css  js  c++  java
  • (Trie + DP) 623. K Edit Distance

     

    思路:前缀树来存储字符串的所有前缀。

     1. 状态转移方程:

     2. 计算顺序

    class Solution {
    public:
        /**
         * @param words: a set of stirngs
         * @param target: a target string
         * @param k: An integer
         * @return: output all the strings that meet the requirements
         */
        struct TrieNode{
            TrieNode* child[26];
            bool is_word;
            string str;
            TrieNode(): is_word(false), str(""){
                for(auto& a:child)
                    a = NULL;
            }
            ~TrieNode(){
                delete[] child;
            }
        };
        
        struct Trie{
            TrieNode* root = new TrieNode();
            void insert(string word){
                TrieNode* p = root;
                for(char a: word){
                    int i = a - 'a';
                    if(!p->child[i])
                        p->child[i] = new TrieNode();
                    p = p->child[i];
                }
                p->is_word = true;
                p->str = word;
            }
        };
        
        //at node p, prefix Sp
        //f means f[Sp][0~n]
        //todo: Sp -> (Sp,'a')...(Sp,'z') 推导从Sp到更长的前缀
        void dfs(TrieNode* p, vector<int>& f, vector<string>& res, string& target, int k){
            int n = target.size();
            vector<int> nf(n+1, 0);   //新的f
            //whether p has word
            if(p->is_word && f[n] <= k){
                //p是一个完整的单词
                res.push_back(p->str);
            }
            
            //f[Sp][j]:一个前缀Sp和Target前j个字符的最小编辑距离
            //f[i][0] = i
            //f[0] = f[Sp][0] = |Sp|
            nf[0] = f[0] + 1;
     
            for(int i=0;i<26; i++){
                //next char is i
                if(p->child[i] == NULL)
                    continue;
                //拓展它的儿子
                for(int j=1; j<=n; j++){
                    //f[i][j] = min( f[i][j-1]+1), f[i-1][j]+1, f[i-1][j-1]+1
                    nf[j] = min(min(nf[j-1]+1, f[j]+1), f[j-1]+1);
                    int c = target[j-1] - 'a';
                    if(c == i){
                    //f[i][j] = min(f[i][j], f[i-1][j-1]), when A[i-1]==target[j-1]
                       nf[j] = min(nf[j], f[j-1]); 
                    }
                }
                dfs(p->child[i], nf, res, target, k);
            }
            
        }
        
        
        vector<string> kDistance(vector<string> &words, string &target, int k) {
            // write your code here
            int n = target.size();
            vector<int> f(n+1,0);
            vector<string> result;
            
            //init Trie
            Trie trie;
            for(string& word: words){
                trie.insert(word);
            }
            TrieNode * p = trie.root;
            //init f
            //f[""][0~n]  前缀为空串时与Target的前n+1个字符的最小编辑距离
            for(int i=0; i<=n; i++){
                f[i] = i;
            }
            
            //dfs
            dfs(p, f, result, target, k);
            //return result
            return result;
        }
    };
  • 相关阅读:
    delphi SysErrorMessage 函数和系统错误信息表 good
    Delphi中ShellExecute使用详解(详细解释10种显示状态)
    几个获取Windows系统信息的Delphi程序
    判断操作系统多久没有任何操作
    MVC4+WebApi+Redis Session共享练习(下)
    MVC4+WebApi+Redis Session共享练习(上)
    EntityFramework使用总结(与MVC4.0实现CURD操作)
    MVC3.0+knockout.js+Ajax 实现简单的增删改查
    基于Redis缓存的Session共享(附源码)
    Redis缓存服务搭建及实现数据读写
  • 原文地址:https://www.cnblogs.com/Bella2017/p/11359850.html
Copyright © 2011-2022 走看看