[leetcode] Substring with Concatenation of All Words 解题报告

题目链接:https://leetcode.com/problems/substring-with-concatenation-of-all-words/

You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in wordsexactly once and without any intervening characters.

For example, given:
s"barfoothefoobarman"
words["foo", "bar"]

You should return the indices: [0,9].
(order does not matter).


思路:和Longest Palindromic Substring 还有 Minimum Window Substring 是一个类型的题目。所以我们要把字典中的单词映射到一个hash table中去,还需要一个辅助hash table和一个计数器来记录当前已经找到的单词和他的数目。刚开始考虑了很多种情况,发现情况越考虑越多,错了几次之后就不想管了,按照一个最简洁的思路来实现。

同样设置一个左右指针来维护一个窗口,每次操作有两种情况:

1. 如果当前子串在字典中,并且数目也不超过字典中的数目,则右指针滑动一个单词的大小继续寻找下一个单词

2. 如果当前子串不在字典中,或者超出了字典中此单词的数量,那么left指针向右滑动一位,同时右指针也滑动到和左指针相同的位置重新开始计算。

这种方法简直是简单粗暴,哈哈,最终我还是打败了3%的程序大笑,成功A掉了这题,那就这样吧!

时间复杂度大概是O(n*n),空间复杂度为O(n)。

[leetcode] Substring with Concatenation of All Words 解题报告_第1张图片


代码如下:

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        vector<int> result;
        if(s.size() == 0 || words.size() == 0)
            return result;
        int left =0, right = 0, find =0;
        unordered_map<string, int> hash;
        unordered_map<string, int> strState;
        for(int i = 0; i< (int)words.size(); i++)
            hash[words[i]]++;
    
        while(right < (int)s.size())
        {
            string tem = s.substr(right, words[0].size());
            if(hash.find(tem) != hash.end() && (strState.find(tem) == strState.end() || strState[tem] < hash[tem]))
            {
                //第一次出现,则为1,否则计数加1
                strState[tem] = (strState.find(tem)==strState.end())?1:(strState[tem]+1);
                find++;
                //找到了所有的单词,则保存结果,并且情况计数器,左指针向右滑动一位,重新开始计数
                if(find == (int)words.size())
                {
                    result.push_back(left);
                    strState.clear();
                    left++;
                    right = left;
                    find = 0;
                }
                else//当前单词在字典中,但是还没有将字典中的单词全部找到,则右指针滑动一个单词的长度
                    right += words[0].size();
            }
            else//如果当前的单词不在字典中,或者超出了字典中此单词的数量,则左指针向右滑动一位重新开始计数
            {
                strState.clear();
                find = 0;
                left++;
                right = left;
            }
        }
        return result;
    }
};


你可能感兴趣的:(LeetCode,算法,String,table,hash,substring)