• 【LeetCode 30】串联所有单词的子串


    题目链接

    【题解】

    开个字典树记录下所有的单词。 然后注意题目的已知条件 每个单词的长度都是一样的。 这就说明不会出现某个字符串是另外一个字符串的前缀的情况(除非相同). 所以可以贪心地匹配(遇到什么字符就在字典树里面沿着边从根往下走就好). 假设给的单词的个数为len.(每个单词的长度都是L) 显然从每个位置开始都要匹配len次。而且每次都要匹配L个字符。 然后因为可能会出现一个单词出现多次的情况。 那么你得记录一下之前某个单词用了多少次。

    【代码】

    class Solution {
    public:
        
        int tree[100000][26+5],tot;
        int tag[100000];
        int used[100000];
        vector<int> visits;
        
        vector<int> findSubstring(string s, vector<string>& words) {
            vector<int> ans;ans.clear();
            if (s=="" || words.empty()) return ans;
            memset(tree,0,sizeof tree);
            memset(tag,0,sizeof tag);
            tot = 1;
            int lendic = words.size();
            for (int i = 0;i < lendic;i++){
                if (i>0 && ((int)words[i].size()!=(int)words[0].size())) return ans;
                string ts = words[i];
                int len2 = ts.size();
                int p = 1;
                for (int j = 0;j < len2;j++){
                    if (tree[p][ts[j]-'a']==0){
                        tree[p][ts[j]-'a'] = ++tot;
                    }
                    p = tree[p][ts[j]-'a'];
                }
                tag[p]++;
            }
            int L = words[0].size();
            int len = s.size();
            for (int i = 0;i < len;i++){
                bool ok = true;
                visits.clear();
                for (int j = 0;j < lendic;j++){//要匹配字典里面的单词个数次
                    int p = 1;
                    for (int k = i+j*L;k < i+(j+1)*L;k++){//每次匹配的长度是固定的
                        if (k>=len){
                            ok = false;
                            break;
                        }
                        if (tree[p][s[k]-'a']==0){
                            ok = false;
                            break;
                        }
                        p = tree[p][s[k]-'a'];
                    }
                    if (!ok) break;
                    if (tag[p]==0) { ok=false;break;}//如果字典里没有这个单词就停止
                    if (used[p]==0) visits.push_back(p);//记录一下哪些位置用到了,之后清0用
                    used[p]++;
                    if (used[p]>tag[p]){//如果用的次数超过单词的个数了,则不行。
                        ok = false;
                        break;
                    }
                }
                for (int x:visits) used[x]=0;
                if (ok) ans.push_back(i);
            }
            return ans;
        }
    };
    
  • 相关阅读:
    6.Mysql之MGR的限制和局限性
    5.Mysql之MGR原理浅谈02
    2.shell之cut详解
    1.Shell编程的基本语法01
    4.Mysql之MGR浅谈01
    3.Mysql之MHA实战(03)
    2.Mysql之高可用架构MHA(02)
    1.数据库的三大范式是什么?
    1.Mysql之主从复制浅谈01
    6.Mydumper和Myloader备份恢复
  • 原文地址:https://www.cnblogs.com/AWCXV/p/11835982.html
Copyright © 2020-2023  润新知