• 【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 };
     
     
     
  • 相关阅读:
    微信小程序开发学习--页面事件和数据绑定
    检测小程序版本更新提示
    vue-cli脚手架
    链表中倒数第K个结点
    调整数组顺序使奇数位于偶数前面
    数值的整数次方(十二)
    二进制中1的个数(十一)
    覆盖矩形(十)
    变态跳台阶(九)
    跳台阶(八)
  • 原文地址:https://www.cnblogs.com/reachteam/p/4229927.html
Copyright © 2020-2023  润新知