• Leetcode 30. 串联所有单词的子串


    地址 https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/

    给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。
    
    注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。
    
     
    示例 1:
    输入:
      s = "barfoothefoobarman",
      words = ["foo","bar"]
    输出:[0,9]
    解释:
    从索引 09 开始的子串分别是 "barfoo""foobar" 。
    输出的顺序不重要, [9,0] 也是有效答案。
    
    
    示例 2:
    输入:
      s = "wordgoodgoodgoodbestword",
      words = ["word","good","best","word"]
    输出:[]

    解答 1

    做了几个表 代码比较简洁 但是效率较低 

    做了一个数组每个位置开头能够对应字典中的那个单词的表格 加速查询

    然后遍历数组 尝试每个位置开头能否有连续的包含字典全部单词的可能

    效率一般

    class Solution {
    public:
        string strArr[10010];
        unordered_map<string, int> mm;
    
        bool Check(const string& s, int idx, const vector<string>& words)
        {
            int l = idx; int count = words.size();
            int needLen = count * words[0].size();
    
            unordered_map<string, int> mmCopy = mm;
    
            while (l <s.size()) {
                string curr = strArr[l];
                mmCopy[curr]--; count--;
                if (mmCopy[curr] < 0) return false;
                if (count == 0) return true;
    
                l = l + words[0].size();
            }
    
    
            return count==0;
        }
    
        vector<int> findSubstring(string s, vector<string>& words) {
            int len = words[0].size();
            vector<int> ans;
            if (len > s.size()) return ans;
    
            for (int i = 0; i < words.size(); i++) {
                mm[words[i]] ++;
            }
    
            for (int i = 0; i <= s.size() - len; i++) {
                string subS = s.substr(i, len);
                if (mm.count(subS) != 0) {
                    strArr[i] = subS;
                }
            }
            
            for (int i = 0; i <= s.size() - len; i++) {
                if (!strArr[i].empty()) {
                    if (Check(s, i, words))  ans.push_back(i);
                }
            }
    
            return ans;
        }
    };

     解法2 

    第二种方法是双指针 但是计算的跨越的长度是单个单词的长度。

    class Solution {
    public:
        vector<int> ans;
        unordered_map<string, int> mm;
    
        void Check(const string& s, const vector<string>& words, int idx) {
            int len = words[0].size();
            int l = idx; int r = idx;
    
            unordered_map<string, int> currM;
    
            while (l < s.size() && r < s.size() && l <= r) {
                string w = s.substr(r, len);
                r += len;
                if (mm.count(w) != 0) {
                    currM[w]++;
                    while (currM[w] > mm[w] && l<r) {
                        string remove = s.substr(l, len);
                        currM[remove]--; l += len;
                    }
    
                    if (currM[w] == mm[w]) {
                        int find = 1;
                        for (auto& e : mm) {
                            if (e.second != currM[e.first]) { find = 0; break; }
                        }
                        if (find == 1) {
                            ans.push_back(l);
                        }
                    }
                }
                else {
                    l = r; currM.clear();
                }
            }
    
    
        }
    
        vector<int> findSubstring(string s, vector<string>& words) {
            for (auto& e : words) { mm[e]++; }
            
            int len = words[0].size();
    
            if (s.size() < words.size()*len) return ans;
    
            for (int i = 0; i < words[0].size(); i++) {
                Check(s,words,i);
            }
    
    
            return ans;
        }
    };
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    基数排序
    希尔排序
    归并排序
    选择排序
    冒泡排序
    堆排序
    快速排序
    Python selenium 4种常用定位 id,class_name,text,xpath
    python selenium 用索引值定位
    python pycharm 建立新项目时使用上个项目所下载的第三方库方法
  • 原文地址:https://www.cnblogs.com/itdef/p/14525399.html
Copyright © 2020-2023  润新知