Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
leetcode刷题30串联所有单词的子串
前文
本文为leetcode字符串类型题目,题目序号为30,主要考察对于字符串的处理效率。
题目信息
给定一个字符串 s 和一些 长度相同 的单词 words 。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。
注意子串要与 words 中的单词完全匹配,中间不能有其他字符 ,但不需要考虑 words 中单词串联的顺序。
解题思路
根据题目信息,想要在目标字符串中找到我们需要的满足条件的字符串,主要采用map来解决这一问题。预先将目标数组装进map中保存。而与此同时,对于原字符串进行滑动遍历,将窗口设置为数组中所有字符串长度之和。向前遍历的过程中,将对应的字符串转为map,并与之前的map进行比较确定是否存储结果数组。按此方式遍历完成,考虑一些特殊情况,即可得到最终的目标结果。
解题代码
public List<Integer> findSubstring(String s, String[] words) {
List<Integer> result = new ArrayList<>();
if(words.length == 0){
return result;
}
Map<String,Integer> map = new HashMap<>();
int length = 0;
int itemLength = -1;
for (int i = 0; i < words.length; i++) {
map.put(words[i],map.getOrDefault(words[i],0) + 1);
length += words[i].length();
itemLength = words[i].length();
}
if(length > s.length()){
return result;
}
for (int i = 0; i <= s.length() - length; i++) {
String str = s.substring(i,i + length);
if(str.length() != length){
break;
}
Map<String,Integer> itemMap = new HashMap<>();
for (int j = 0; j < length/itemLength; j++) {
itemMap.put(str.substring(itemLength * j,itemLength * (j + 1)),itemMap.getOrDefault(str.substring(itemLength * j,itemLength * (j + 1)),0) + 1);
}
boolean ok = true;
for (int j = 0; j < words.length; j++) {
if(itemMap.containsKey(words[j]) && itemMap.get(words[j]).equals(map.get(words[j]))){
continue;
}else{
ok = false;
break;
}
}
if(ok){
result.add(i);
}
}
return result;
}
后记
- 千古兴亡多少事?悠悠。不尽长江滚滚流。