⭐️寒假新坑——代码之狐的每日做题笔记
30. 串联所有单词的子串-Hard
题目描述:
给定一个字符串 s
和一些 长度相同 的单词 words
**。**找出 s
中恰好可以由 words
中所有单词串联形成的子串的起始位置。
注意子串要与 words
中的单词完全匹配,中间不能有其他字符 ,但不需要考虑 words
中单词串联的顺序。
解题思路:
-
使用一个数组count[][]保存words数组中每种字符串出现的次数,并利用一个HashMap保存字符串与其在count中的位置对应,比如<“word”,0>表示"word"字符串在words中出现次数保存在count[0]=2中,出现了两次。
-
历遍一次s,判定每个s中的长度为word.length的子字符串是否是words中的字符,使用HashMap快速查找其在count中的位置,并使用一个数组indexS保存,如果不是保存-1;
-
再次历遍indexS数组,每次查找i、i+word.length、i+2 * word.length、…、i+(words.length-1)* word.length,统计其是否有对应的words,并记录在数组judge中,如果出现-1(表示,该子字符串存在不能被words匹配的片段),立即退出;统计完成后,匹配是否与count对应,如果对应,则记录一次结果
代码实现:
class Solution {
public List<Integer> findSubstring(String s, String[] words) {
int wL=words[0].length();
int sL=s.length();
int wN=words.length;
Map<String,Integer> map=new HashMap<>();
for(String i:words){
map.put(i,map.getOrDefault(i,0)+1);
}
int[] count=new int[map.size()];
int countI=0;
for(Map.Entry<String,Integer> e:map.entrySet()){
count[countI]=e.getValue();
map.put(e.getKey(),countI);
countI++;
}
int indexSL=sL-wL+1;
int[] indexS=new int[indexSL];
for(int i=0;i<indexSL;i++){
indexS[i]=map.getOrDefault(s.substring(i,i+wL),-1);
}
List<Integer> ans=new ArrayList<>();
for(int i=0;i<indexSL;i++){
int[] judge=new int[count.length];
int iR=i+(wN-1)*wL;
if(iR>=indexSL){
break;
}
for(int k=i;k<=iR;k+=wL){
if(indexS[k]==-1){
break;
}
else{
judge[indexS[k]]++;
}
}
boolean equal=true;
for(int z=0;z<count.length;z++){
if(judge[z]!=count[z]){
equal=false;
break;
}
}
if(equal){
ans.add(i);
}
}
return ans;
}
}
结尾
题目来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems
⭐️关注作者,带你刷题,从简单的算法题了解最常用的算法技能(寒假每日一题)
⭐️关注作者刷题——简单到进阶,让你不知不觉成为无情的刷题机器,有问题请私信