leetCode(30) - Substring with Concatenation of All Words

本文介绍了一种用于查找字符串中特定模式的算法。该算法能够高效地找出由一组固定长度单词构成的所有组合出现的位置。通过使用哈希表进行单词匹配计数,文章提供了C语言和C++实现的详细代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem:

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

Solution:

由于长度是固定的,因此固定每一个字符串开始的位置,然后向后搜索,查看每一个字符串是否存在,如果不存在i++

C语言源代码(260ms):

sub不free的话会MLE
  1. typedef struct Node{  
  2.     char* word;  
  3.     int times;  
  4.     struct Node* next;  
  5. }data;  
  6. #define SIZE 1000  
  7. int hash(char* word){  
  8.     int i=0,h=0;  
  9.     for(;word[i];i++){  
  10.         h=(h*31+word[i])%SIZE;  
  11.     }  
  12.     return h;  
  13. }  
  14. int InsertMap(data** map,char* word,int lenw){  
  15.     int h = hash(word);  
  16.     if(map[h]==NULL){  
  17.         map[h]=(data*)malloc(sizeof(data));  
  18.         map[h]->word=(char*)malloc(sizeof(char)*(lenw+1));  
  19.         map[h]->times=1;  
  20.         strcpy(map[h]->word,word);  
  21.         map[h]->next=NULL;  
  22.         return 1;  
  23.     }else{  
  24.         data* p=map[h];  
  25.         while(p->next!=NULL){  
  26.             if(strcmp(p->word,word)==0){  
  27.                 p->times++;  
  28.                 return p->times;  
  29.             }  
  30.             p=p->next;  
  31.         }  
  32.         if(strcmp(p->word,word)==0){  
  33.             p->times++;  
  34.             return p->times;  
  35.         }else{  
  36.             data* tmp=(data*)malloc(sizeof(data));  
  37.             tmp->word=(char*)malloc(sizeof(char)*(lenw+1));  
  38.             tmp->times=1;  
  39.             strcpy(tmp->word,word);  
  40.             tmp->next=NULL;  
  41.             p->next=tmp;  
  42.             return 1;  
  43.         }  
  44.     }  
  45. }  
  46. int FindMap(data** map,char* sub){  
  47.     int h = hash(sub);  
  48.     if(map[h]==NULL){  
  49.         return -1;  
  50.     }else{  
  51.         data* p=map[h];  
  52.         while(p!=NULL){  
  53.             if(strcmp(p->word,sub)==0){  
  54.                 return p->times;  
  55.             }  
  56.             p=p->next;  
  57.         }  
  58.         return -1;  
  59.     }  
  60. }  
  61. char* substring(char* s,int start,int len){  
  62.     char* sub=(char*)malloc(sizeof(char)*(len+1));  
  63.     int i=0;  
  64.     for(;i<len;i++){  
  65.         sub[i]=s[i+start];  
  66.     }  
  67.     sub[i]=0;  
  68.     return sub;  
  69. }  
  70. int* findSubstring(char* s, char** words, int wordsSize, int* returnSize) {  
  71.     int lenw=strlen(words[0]),lens=strlen(s),length=wordsSize;  
  72.     int* res=(int*)malloc(sizeof(int)*(lens-lenw*length+1));  
  73.     data** map=(data**)malloc(sizeof(data*)*SIZE);  
  74.     data** tmp=(data**)malloc(sizeof(data*)*SIZE);  
  75.     int i,j;  
  76.     for(i=0;i<SIZE;i++){  
  77.         map[i]=NULL;  
  78.         tmp[i]=NULL;  
  79.     }  
  80.     for(i=0;i<length;i++){  
  81.         InsertMap(map,words[i],lenw);  
  82.     }  
  83.     *returnSize=0;  
  84.     for(i=0;i<lens-lenw*length+1;i++){  
  85.         for(j=0;j<SIZE;j++){  
  86.             if(tmp[j]!=NULL){  
  87.                 free(tmp[j]);  
  88.                 tmp[j]=NULL;  
  89.             }  
  90.         }  
  91.         for(j=0;j<length;j++){  
  92.             char* sub=substring(s,i+j*lenw,lenw);  
  93.             int mapnum=FindMap(map,sub);  
  94.             if(mapnum==-1)break;  
  95.             int num=InsertMap(tmp,sub,lenw);  
  96.             if(mapnum < num)break;  
  97.             free(sub);  
  98.         }  
  99.         if(j>=length)res[(*returnSize)++]=i;  
  100.     }  
  101.     for(i=0;i<SIZE;i++)if(map[i]!=NULL)free(map[i]);  
  102.     free(map);  
  103.     return res;  
  104. }  

C++源代码(704ms):

  1. class Solution {  
  2. public:  
  3.     vector<int> findSubstring(string s, vector<string>& words) {  
  4.         int lens=s.size(),lenw=words[0].size(),length=words.size();  
  5.         map<string,int> strmap,tmp;  
  6.         for(int i=0;i<length;i++){  
  7.             strmap[words[i]]++;  
  8.         }  
  9.         vector<int> res;  
  10.         for(int i=0;i<lens-lenw*length+1;i++){  
  11.             tmp.clear();  
  12.             int j=0;  
  13.             for(j=0;j<length;j++){  
  14.                 string sub=s.substr(i+j*lenw,lenw);  
  15.                 if(strmap.find(sub) == strmap.end())break;  
  16.                 tmp[sub]++;  
  17.                 if(strmap[sub] < tmp[sub])break;  
  18.             }  
  19.             if(j>=length)res.push_back(i);  
  20.         }  
  21.         return res;  
  22.     }  
  23. };  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值