LeetCode | Substring with Concatenation of All Words

题目:

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

For example, given:
S"barfoothefoobarman"
L["foo", "bar"]

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

思路:

假设len表示L字串的长度,num表示L字串的数目。

需要用S中的字母与L中的字符串中的字母一个一个去比较,所有比较成功则产生一个结果,否则会发生回溯。由于有回溯存在,势必需要字符串会被重复比较。因此我们可以利用动态规划的观点来存储S中的字串与L的关系。 sameWord用来存储这个结果,sameWord[k]表示从k开始,长度为L中字符串长度的S中字符串与L中的第几个字符串匹配。

第二个问题是,L中的字符串可能有重复。所以我们需要有一个map结果来保存字符串与其对应的编号。L中的重复字符串就应当对应相应的编号。代码中的words就是这样的结果。

第三个问题是,我们不仅要用编号来排除重复的字符串,还需要保存字符串重复的次数。因此我们引入了dict来保持重复次数。

以上问题解决之后,我们只需要带回溯的循环一次来依次查看从i开始,长度为len*num的S字串与L所有字串的关系。

代码:

class Solution {
public:
    vector<int> findSubstring(string S, vector<string> &L) {
        vector<int> r;
        
        int len=L[0].size();
        int num=L.size();
        
        unordered_map<string,int> words;
        vector<int> dict;
        int count=0;
        for(int i=0;i<L.size();i++)
        {
            unordered_map<string,int>::const_iterator got = words.find (L[i]);
            if(got==words.end())
            {
                pair<string,int> item(L[i],count);
                words.insert(item);
                dict.push_back(1);
                count++;
            }
            else
            {
                dict[got->second]++;
            }
        }
        //建立L中字符串(重复)与其对应的编号,以及每个编号字符串出现的次数
        
        int* sameWord = new int [S.size()];
        for(int i=0;i+len<=S.size();i++)
        {
            unordered_map<string,int>::const_iterator got = words.find (S.substr(i,len));
            if(got != words.end())
            {
                sameWord[i] = got->second;
            }
            else
            {
                sameWord[i] = -1;
            }
        }
        //建立动态规划方程来记录i开始,长度为len的S字串与L字符串的关系
        
        for(int k=0;k+len*num<=S.size();k++)
        {
            int begin=k;
            vector<int> tmp = dict;
            bool found = true;
            int total = num;
            while(total>0)
            {
                int index = sameWord[begin];
                
                if(index == -1)
                {
                    found = false;
                    break;
                }
                else
                {
                    if(tmp[index]>0)
                    {
                        tmp[index]--;
                        total--;
                        begin+=len;
                    }
                    else
                    {
                        found = false;
                        break;
                    }
                }
            };
            if(found)
            {
                r.push_back(k);
            }
        }
        //每次循环查看,长度为len*num的字串能否涵盖所有的L字串
        return r;
    }
};
    原文作者:Allanxl
    原文地址: https://blog.csdn.net/lanxu_yy/article/details/17716651
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞