公众号merlinsea
题目描述
给定一个字符串 s 和一些 长度相同 的单词 words 。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。注意子串要与 words 中的单词完全匹配,中间不能有其他字符 ,但不需要考虑 words 中单词串联的顺序。
链接:https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words
示例
输入:s = "barfoothefoobarman", words = ["foo","bar"] 输出:[0,9] 解释: 从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。 输出的顺序不重要, [9,0] 也是有效答案。
解题思路:
双hashMap+滑动窗口实现。这种题目特点就是条件要求全部满足的连续子序列, 如果出现了条件不满足的情况就应该停下来通过移动左边界直至条件满足才能继续向下 执行。
代码实现:
class Solution { private Map<String,Integer> map = new HashMap<>(); public List<Integer> findSubstring(String s, String[] words) { ArrayList<Integer> list = new ArrayList<>(); int oneWordLen = words[0].length(); for(String word : words){ map.put(word,map.getOrDefault(word,0)+1); } for(int i = 0;i<oneWordLen;i++){ int left = i; int right = i; int count = 0; Map<String,Integer> tempMap = new HashMap<>(); while(right+oneWordLen<=s.length()){ String word = s.substring(right,right+oneWordLen); right = right+oneWordLen; if(!map.containsKey(word)){ //当前word不在map中,那么不论怎么移动left都无济于事 count=0; tempMap.clear(); left=right; }else{ count++; tempMap.put(word,tempMap.getOrDefault(word,0)+1); while(tempMap.get(word) > map.get(word)){ //出现了条件不满足的情况应该停下来移动左边界直到条件满足为止 String firstWord = s.substring(left,left+oneWordLen); left = left+oneWordLen; tempMap.put(firstWord,tempMap.get(firstWord)-1); count--; } if(count==words.length){ list.add(left); count--; String firstWord = s.substring(left,left+oneWordLen); left=left+oneWordLen; tempMap.put(firstWord,tempMap.get(firstWord)-1); } } } } return list; } }