【leetcode】Substring with Concatenation of All Words

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).

 
第一种简单的思路:
用两个map,一个map用于表示L中各个单词的数目,另一个map用于统计当前遍历S得到的单词的数目
 
从第0个,第1个,第2个位置开始遍历S串
统计得到的单词的数目,如果某个单词数目超出了L中该单词的数目,或者某个单词没有再L中出现,则重新从下一个位置开始统计
 
 1 class Solution {

 2 public:

 3     vector<int> findSubstring(string S, vector<string> &L) {

 4        

 5         if(L.size()==0) return vector<int>();

 6        

 7         int wordLen=L[0].size();

 8        

 9         map<string,int> wordCount;

10        

11         int i,j;

12         for(i=0;i<L.size();i++)  wordCount[L[i]]++;

13        

14        

15         vector<int> result;

16         map<string,int> counting;

17        

18         for(i=0;i<(int)S.length()-wordLen*L.size()+1;i++)

19         {

20             counting.clear();

21             for(j=0;j<L.size();j++)

22             {

23                 string str=S.substr(i+j*wordLen,wordLen);

24                 if(wordCount.find(str)!=wordCount.end())

25                 {

26                     counting[str]++;

27                     if(counting[str]>wordCount[str])

28                     {

29                         break;

30                     }

31                 }

32                 else

33                 {

34                     break;

35                 }

36             }

37            

38             if(j==L.size())

39             {

40                 result.push_back(i);

41                 //i=i+L.size()*wordLen-1;

42             }

43         }

44        

45         return result;

46  

47     }

48 };

 

 
 
 
第二种思路,维护一个窗口,在遍历时分别要从0,1……wordLen开始遍历一遍,防止遗漏
 
如果发现某个单词不在L中,则从下一个位置开始,重新统计
如果发现某个单词出现的次数多了,则需从这个单词第一次出现位置的后面一位开始统计,并要剔除这个位置之前统计的一些结果
 
 1 class Solution {

 2 public:

 3     vector<int> findSubstring(string S, vector<string> &L) {

 4        

 5         if(L.size()==0) return vector<int>();

 6        

 7         int wordLen=L[0].size();

 8        

 9         map<string,int> wordCount;

10        

11         int i,j;

12         for(i=0;i<L.size();i++)  wordCount[L[i]]++;

13        

14        

15         vector<int> result;

16         map<string,int> counting;

17        

18        

19         int count=0;

20         int start;

21        

22         for(i=0;i<wordLen;i++)

23         {

24             count=0;

25             start=i;

26             counting.clear();

27             for(int j=i;j<S.length()-wordLen+1;j=j+wordLen)

28             {

29                 string str=S.substr(j,wordLen);

30                

31                 if(wordCount.find(str)!=wordCount.end())

32                 {

33                     counting[str]++;

34                     count++;

35                     if(counting[str]>wordCount[str])

36                     {

37                         //更新start位于str第一次出现之后,更新counting,更新count

38                         getNextIndex(start,str,counting,S,wordLen,count);

39                     }

40                 }

41                 else

42                 {

43                     counting.clear();

44                     start=j+wordLen;

45                     count=0;

46                 }

47                

48                 if(count==L.size())

49                 {

50                     result.push_back(start);

51                 }

52             }

53         }

54         return result;

55     }

56    

57    

58     void getNextIndex(int &start,string str,map<string,int> &counting,string &S,int &wordLen,int &count)

59     {

60         for(int j=0;;j++)

61         {

62             string tmpStr=S.substr(start+j*wordLen,wordLen);

63             count--;

64             counting[tmpStr]--;

65             if(tmpStr==str)

66             {

67                 start=start+(j+1)*wordLen;

68                 break;

69             }

70         }

71        

72     }

73 };

 

 
 
 

你可能感兴趣的:(substring)