Leetcode 30. Substring with Concatenation of All Words
2016-05-15 10:00
411 查看
30. Substring with Concatenation of All Words
Total Accepted: 54574 TotalSubmissions: 261476 Difficulty: Hard
You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that
is a concatenation of each word in wordsexactly once and without any intervening characters.
For example, given:
s:
"barfoothefoobarman"
words:
["foo", "bar"]
You should return the indices:
[0,9].
(order does not matter).
解法一:参考这里
先统计words中的单词和频率。然后从每个位置开始,判断长度为words.length*words[0].length()的字符串满足要求否,因为不满足会直接break,所以判断长度最多为那么长。每次判断新建一个Map复制之前的数据,这样保证单词出现一次并且只有一次。
public class Solution { // 190ms public List<Integer> findSubstring(String s, String[] words) { List<Integer> res = new ArrayList<Integer>(); if(s == null || s.length()==0) return res; Map<String, Integer> hm = new HashMap<String, Integer>(); int n = words.length, m = words[0].length(), l = s.length(); for(int i=0; i<n; i++){ if(hm.containsKey(words[i])){ hm.put(words[i], hm.get(words[i])+1); }else{ hm.put(words[i], 1); } } for(int i=0; l-i>=m*n; i++){ Map<String, Integer> temp = new HashMap<String, Integer>(hm); for(int j=0; j<n; j++){ String substr = s.substring(i+j*m, i+(j+1)*m); if(temp.containsKey(substr)){ if(temp.get(substr)==1) temp.remove(substr); else temp.put(substr, temp.get(substr)-1); }else{ break; } } if (temp.size()==0) res.add(i); } // int i = 0; // 不同写法,和上面运行时间一样,但是上面的for loop 经常报超时(80%概率)。 // while(l-i>=m*n){ // Map<String, Integer> temp = new HashMap<String, Integer>(hm); // for(int j=0; j<n; j++){ // String substr = s.substring(i+j*m, i+(j+1)*m); // if(temp.containsKey(substr)){ // if(temp.get(substr)==1) temp.remove(substr); // else temp.put(substr, temp.get(substr)-1); // }else{ // break; // } // } // if (temp.size()==0) res.add(i); i++; // } return res; } }
解法二:解释大概和这里相同,code来自这里。
思路是start的位置有单词长度个。然后end指针从start开始,如果从end开始的单词长度的字符串不在词典里,那么start指针右移单词个长度;否则当前的map中该单词频率+1,并判断子窗口的长度是否满足要求,满足则start加入结果中。有一种情况是碰到重复的,则需要跳过从start开始的子串,直到使当前发生dup的单词频率减少,此过程中start不断变化,相当于更新起点。
public class Solution{ // 20ms public ArrayList<Integer> findSubstring(String S, String[] L) { final Map<String, Integer> need = new HashMap<String, Integer>(); for (int i = 0; i < L.length; i++) { need.put(L[i], need.get(L[i]) == null ? 1 : need.get(L[i]) + 1); } ArrayList<Integer> result = new ArrayList<Integer>(); for (int i = 0; i < L[0].length(); i++) { // 只有单词长度个开始位置,防止重复。 populateResult(result, S, L, i, need); } return result; } private void populateResult(ArrayList<Integer> result, String S, String[] L, int start, final Map<String, Integer> need) { int k = L[0].length(); HashMap<String, Integer> has = new HashMap<String, Integer>(); for (int end = start; end <= S.length() - k; end += k) { String sub = S.substring(end, end + k); if (need.containsKey(sub)) { while (has.get(sub) == need.get(sub)) { // 遇到与sub重复的,则跳过开始已匹配的子串,直到去除重复的sub String tmp = S.substring(start, start + k); has.put(tmp, has.get(tmp) - 1); start += k; } has.put(sub, has.get(sub) == null ? 1 : has.get(sub) + 1); if (end - start + k == L.length * L[0].length()) result.add(start); } else { has.clear(); start = end + k; } } } }
相关文章推荐
- 2016"百度之星" - 资格赛(Astar Round1) Problem E
- 什么是ionic
- Solution104: Maximum Depth of Binary Tree
- 基于SSH框架的学生选课质量属性分析
- hdu1828 Picture (矩形周长并+扫描线)
- YJX_rxjh_18_3.1.2
- hdu-5680 zxa and set(水题)
- 2016"百度之星" - 资格赛(Astar Round1) Problem D
- 2016"百度之星" - 资格赛(Astar Round1) Problem C
- 1.5、ServletRequestAttributeListener和HttpSessionAttributeListener监听器范例
- java基础---->摘要算法的介绍
- Centos以rpm方式进行安装MySql
- Java关键字final、static使用总结(转)
- js停止冒泡和阻止浏览器默认行为的简单方法
- XHTML+CSS 文字加粗的方式[学习笔记]
- Spring配置多个ViewResolver
- iOS - block、代理、通知
- The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Cha
- Mybatis
- build.gradle中引入jar