Substring with Concatenation of All Words, 返回字符串中包含字符串数组所有字符串元素连接而成的字串的位置
问题描述:给定一个字符数组words,和字符串s,返回字符数组中所有字符元素组成的子串在字符串中的位置,要求所有的字符串数组里的元素只在字符串s中存在一次。
算法分析:这道题和strStr很类似。只不过strStr是子串,而这个题是字符串数组里的元素组成的子串,字符串数组里的元素是无序的,但是必须全部包含。所有考虑使用map集合。关键点在于几个临界值,字符串元素在s中重复了怎么做,找到一个符合的子串后怎么做,有字符串元素不匹配怎做。
import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class SubstringwithConcatenationofAllWords { public List<Integer> findSubstring(String s, String[] words) { ArrayList<Integer> result = new ArrayList<Integer>(); if(s==null||s.length()==0||words==null||words.length==0){ return result; } //frequency of words HashMap<String, Integer> map = new HashMap<String, Integer>(); for(String w: words){ if(map.containsKey(w)){ map.put(w, map.get(w)+1); }else{ map.put(w, 1); } } int len = words[0].length(); for(int j=0; j<len; j++) { HashMap<String, Integer> currentMap = new HashMap<String, Integer>(); int start = j;//起始下标,因为len为窗口大小,所以起始下标只需在0-len之间循环,就像取模一样,超过了,就重复了。 int count = 0;//记录满足的字符串数量 for(int i=j; i<=s.length()-len; i=i+len) { String sub = s.substring(i, i+len); if(map.containsKey(sub)) { if(currentMap.containsKey(sub)) { currentMap.put(sub, currentMap.get(sub)+1); } else { currentMap.put(sub, 1); } count++; //只要发现子字符串中有重复的字符数组中的元素,那么就从起始位置循环删除字符串. //也就是说重复了,就逆向操作,直至只包含一个重复的那个字符串。 while(currentMap.get(sub)>map.get(sub)) { //四个基本逆向操作。重复了或匹配成功了都要进行窗口滑动。 String left = s.substring(start, start+len); currentMap.put(left, currentMap.get(left)-1); count--; start = start + len; } if(count==words.length)//字符串包含所有字符数组中的元素, { result.add(start); //将起始位置加入result //四个基本逆向操作。窗口滑动。窗口值为len String left = s.substring(start, start+len); currentMap.put(left, currentMap.get(left)-1); count--; start = start + len; } } else { currentMap.clear(); start = i+len; count = 0; } } } return result; } }
StrStr算法如下:
public int strStr(String haystack, String needle) { if(haystack == null || needle == null) { return -1; } for (int i = 0; i <= (haystack.length()-needle.length()); i++) { int m = i; for (int j = 0; j < needle.length(); j++) { if (needle.charAt(j) == haystack.charAt(m)) { m++; if((m-i) == needle.length()) { return i; } } else { break; } } } return -1; }