• [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;
        }
    };
    
  • 相关阅读:
    Xpath语法
    Centos 6.5 本地局域网基于HTTP搭建YUM
    前端接口自动化测试工具-DOClever使用介绍(转载)
    mysql指令
    vue+element+echarts饼状图+可折叠列表
    vue+element+echarts柱状图+列表
    缓冲流
    查询同一张表符合条件的某些数据的id拼接成一个字段返回
    Properties集合
    JDK7&JDK9处理异常新特性
  • 原文地址:https://www.cnblogs.com/chendl111/p/9127091.html
Copyright © 2020-2023  润新知