问题描述:给定一个字符数组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; }
时间: 2024-10-09 20:07:55