zoukankan      html  css  js  c++  java
  • 30. 串联所有单词的子串 (哈希+滑动窗口)

    给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。

    注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。

    示例 1:

    输入:
    s = "barfoothefoobarman",
    words = ["foo","bar"]
    输出:[0,9]
    解释:
    从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。
    输出的顺序不重要, [9,0] 也是有效答案。
    示例 2:

    输入:
    s = "wordgoodgoodgoodbestword",
    words = ["word","good","best","word"]
    输出:[]

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    //map 和滑动窗口
    class Solution {
    public:
        vector<int> findSubstring(string s, vector<string>& words) {
            if(!s.length()||!words.size())return {};
            int one_size=words[0].length();//一个单词的大小
            int words_size=words.size();//一共又多少个单词
            int size=one_size*words_size;//需要在s中截取的大小
            if(size>s.length())return {};//
            vector<int> res;
            unordered_map<string,int> target;
            for(auto str:words)target[str]++;//设置目标map
            for(int i=0;i<s.length()-size+1;i++)
            {
                unordered_map<string,int> cur;//当前的map
                for(int k=0;k<words_size;k++)//对当前s中截取的字符串 中的words_size个单词进行map统计
                {
                    string w=s.substr(i+one_size*k,one_size);//截取一个单词
                    if(target.find(w)==target.end())break;//若这个单词在target中没有就结束
                    cur[w]++;//统计当前的map
                }
                if(cur==target)res.push_back(i);//若当前的map等于target的map 将i加入到答案中
            }
            return res;
        }
    };
    //比较map是否相同
    //起始位置从0->one_size
    //然后一次截取one_size个字符串 设置left和right 
    class Solution {
    public:
        vector<int> findSubstring(string s, vector<string>& words) {
            if(!s.length()||!words.size())return {};
            int one_size=words[0].length();//一个单词的大小
            int words_size=words.size();//一共又多少个单词
            int size=one_size*words_size;//需要在s中截取的大小
            if(size>s.length())return {};
            vector<int> res;
            unordered_map<string,int> target;
            for(const auto& str:words)target[str]++;//设置目标map
            for(int start=0;start<one_size;start++)//设置不同的起点 
            {
                int left=start,right=start,count=0;
                unordered_map<string,int> cur;//当前的map
                while(right+one_size<=s.length())
                {
                    string w=s.substr(right,one_size);//截取一个单词
                    right+=one_size;//移动右边界
                    if(target.find(w)==target.end())//若当前单词不在target中 则重置
                    {
                        count=0;
                        cur.clear();
                        left=right;
                    }
                    else
                    {
                        cur[w]++;
                        count++;
                        //为什么是while呢
                        //因为左边第一个单词不一定是w
                        while(target[w]<cur[w])//若当前w的次数大于target中w的次数 则左移
                        {
                            string str=s.substr(left,one_size);
                            cur[str]--;
                            left+=one_size;
                            count--;
                        }
                        if(count==words_size)res.push_back(left);
                    }
                }
            }
            return res;
        }
    };
  • 相关阅读:
    写商业计划书的十个要点
    this page isn't working (ERR_EMPTY_RESPONSE)
    使用meta跳转页面
    fa-list-alt
    在linux下sh批处理文件调用java的方法
    产品使用的前后台框架API-dubbo-redis-elasticsearch-jquery
    JAVA虚拟机关闭钩子(Shutdown Hook)
    xxx is not in the sudoers file.This incident will be reported.的解决方法
    ssh连接docker容器
    namenode namespaceID与datanode namespaceID 不一致导致datanode无法启动的问题
  • 原文地址:https://www.cnblogs.com/lancelee98/p/13468173.html
Copyright © 2011-2022 走看看