zoukankan      html  css  js  c++  java
  • [Lintcode]Word Squares(DFS|字符串)

    题意

    分析

    0.如果直接暴力1000^5会TLE,因此考虑剪枝
    1.如果当前需要插入第i个单词,其剪枝如下
    1.1 其前缀(0~i-1)已经知道,必定在前缀对应的集合中找
    – 第一个词填了ball 后,第二个词必须以a开头
    – 第二个词填了area后,第三个词必须以le开头
    – 以其他开头的就没必要搜下去了
    1.2 第i+1~n-1的单词,必定是以对应位置的0~i-1的前缀+nextWord[k]作为前缀
    — 第一个词填了ball
    – 第二个词想填area的话
    – 字典中必须有以le la开头的单词,否则没有的话就不能填area
    1.3 如何实现?
    利用hash或Trie

    代码

    class Solution {
    public:
        /*
         * @param words: a set of words without duplicates
         * @return: all word squares
         */
        unordered_map<string,vector<string> >prefix;
        vector<string>square;//存储字符串
        vector<vector<string> >result;
        vector<vector<string>> wordSquares(vector<string> &words) {
            // write your code here
            if(words.size()==0) return result;
            initPrefix(words);
            dfs(0);
            return result;
        }
    
        void initPrefix(vector<string>&words)
        {
            for(int i=0;i<words.size();++i)
            {
                string str=words[i];
                prefix[""].push_back(str);
                for(int j=0;j<str.size();++j)//将每个字符串放入对应的前缀
                    prefix[str.substr(0,j+1)].push_back(str);
            }
        }
    
        void dfs(int len)//当前放的行数
        {
            if(len==words[0].size()) 
            {
                result.push_back(square);
                return ;
            }
            string pre;
            //先将所放字符串前缀求出,竖向计算
            for(int i=0;i<len;++i)
            {
                pre+=square[i][len];
            }
            vector<string>w=prefix[pre];//取出前缀有的字符串
            for(int i=0;i<w.size();++i)
            {
                if(!check(len,w[i])) continue;
            }
            square.push_back(w[i]);
            dfs(len+1);
            square.pop_back();
        }
    /*
    check的原则,检查未来插入的字符串是否有相同的前缀
     */
        bool check(int len,string nextWord)
        {
            for(int j=len+1;j<words[0].size();++j)
            {
                string str;
                for(int i=0;i<len;++i) str+=square[i][j];//第j列0~j-1前缀
                str+=nextWord[j];//并加上第j列的字符
                if(!prefix[str].size()) return false;
            }
            return true;
        }
    };
    
  • 相关阅读:
    跨域请求
    django数据模型中关于on_delete, db_constraint的使用
    rest-framework之分页器
    跨域请求
    相对路径与绝对路径
    html常用标签
    ES6中字符串扩展
    javascript中startswith和endsWidth 与 es6中的 startswith 和 endsWidth
    Angular6 组件树结构优化
    docker限制容器内存使用上限
  • 原文地址:https://www.cnblogs.com/chendl111/p/9127091.html
Copyright © 2011-2022 走看看