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).
题解:题目的意思是在S中找到一个子串,恰好包含了L中所有的串,L中的串在S的字串中的顺序不重要。
思路很简单,假设L中共有m个串,每个串长度为n,那么L中子串合并起来总长度是m*n,那么只要在S中依次搜索长度为m*n的串就可以了。在搜索的过程中,设置两个hashmap,一个存放L中的串和它们在L中出现的次数,一个存放在S中m*n的子串中找到的长度为n的串和它们在S的子串中出现的次数,因为查看的是S长度为m*n的子串,并且是n个字符为一组查看的,所以要么在S中看到某个长度为n的子串不出现在L中,要么在S中出现的次数比L中多,否则这个长度为m*n的串就是L的所有串的合并。
例如题目中的例子
- 我们首先查看S的子串barfoo,查看这个子串的时候,按照bar,foo的顺序查看,得知子串foobar是符合要求的
- 再查看子串arfoot,查看顺序是arf,oot,发现arf不在L中,所以arfoot不符合要求;
- 再查看子串rfooth,......
1 if(L == null || L.length == 0) 2 return null; 3 int m = L.length; 4 int n = L[0].length(); 5 //store n-length strings in L 6 HashMap<String, Integer> map = new HashMap<String, Integer>(); 7 //store n-length strings inS 8 HashMap<String, Integer> InS = new HashMap<String, Integer>(); 9 List<Integer> answer = new ArrayList<Integer>(); 10 for(String s:L){ 11 if(!map.containsKey(s)) 12 map.put(s, 1); 13 else { 14 map.put(s, map.get(s)+1); 15 } 16 } 17 18 19 for(int i = 0;i <= S.length() - m*n;i++){ 20 InS.clear(); 21 boolean find = true; 22 for(int j = 0;j < m;j++){ 23 String sub = S.substring(i+j*n,i+(j+1)*n); 24 //if a n-length string in S‘s substring doesn‘t in L, skip to search a new substring in S 25 if(!map.containsKey(sub)){ 26 find = false; 27 break; 28 } 29 if(!InS.containsKey(sub)) 30 InS.put(sub, 1); 31 else { 32 InS.put(sub, InS.get(sub)+1); 33 } 34 //if a n-length string in S‘substring appears more time than in L, stop checking this substring 35 if(InS.get(sub) > map.get(sub)){ 36 find = false; 37 break; 38 } 39 } 40 if(find) 41 answer.add(i); 42 } 43 return answer;
【leetcode刷题笔记】Substring with Concatenation of All Words,布布扣,bubuko.com
时间: 2024-10-12 03:37:37