Leetcode -- Substring with Concatenation of All Words
2015-01-27 15:47
302 查看
问题连接:https://oj.leetcode.com/problems/substring-with-concatenation-of-all-words/
问题描述:
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:
L:
You should return the indices:
(order does not matter).
问题API: public List<Integer> findSubstring(String S, String[] L)
问题分析:这题其实可以当做一个变种的strstr,strstr是一个字符一个字符的match,这里是不计顺序的连续单词match。因为是不计顺序,这个时候哈希表的运用就变得必要了起来,作为一个特殊的计数器。先构造一个类似字典的HashMap。然后再每个起点创造一个新的HashMap作为一个特殊的匹配计数器,依据这个计数器的内容和当前匹配的内容维护一个窗口,里面全是符合条件的字符串。起点的个数是字符串数组里字符串的长度,然后按照strstr的 延伸思想逐个匹配,匹配到字典并符合条件的,窗口便扩大,一旦窗口的大小等于L
* L[0].length,便表示找到了符合条件的答案之一。一旦当前子字符串不在字典内,当前维护的窗口便彻底作废。具体看代码吧:
public List<Integer> findSubstring(String S, String[] L) {
HashMap<String, Integer> cached_map = new HashMap<String, Integer>();
List<Integer> res = new LinkedList<Integer>();
if(L == null || L.length == 0)
return res;
int head = 0;
for(String str : L)
cached_map.put(str, cached_map.containsKey(str) ? cached_map.get(str) + 1 : 1);
for(int i = 0; i < L[0].length(); i++){
int counter = 0;
head = i;
HashMap<String, Integer> cur_map = new HashMap<String, Integer>();
for(int j = i; j <= S.length() - L[0].length(); j += L[0].length()){
String tmp_str = S.substring(j, j + L[0].length());
if(cached_map.containsKey(tmp_str)){
if(!cur_map.containsKey(tmp_str) || cur_map.get(tmp_str) < cached_map.get(tmp_str)){
counter++;
cur_map.put(tmp_str, cur_map.containsKey(tmp_str) ? cur_map.get(tmp_str) + 1 : 1);
if(counter == L.length){
res.add(head);
String remove = S.substring(head, head + L[0].length());
cur_map.put(remove, cur_map.get(remove) - 1);
head += L[0].length();
counter--;
}
}else{
String remove_candidate = S.substring(head, head + L[0].length());
while(!remove_candidate.equals(tmp_str)){
cur_map.put(tmp_str, cur_map.get(remove_candidate) - 1);
head += L[0].length();
counter--;
remove_candidate = S.substring(head, head + L[0].length());
}
head += L[0].length();
}
}else{
head = j + L[0].length();
counter = 0;
cur_map.clear();
}
}
}
return res;
}
问题描述:
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).
问题API: public List<Integer> findSubstring(String S, String[] L)
问题分析:这题其实可以当做一个变种的strstr,strstr是一个字符一个字符的match,这里是不计顺序的连续单词match。因为是不计顺序,这个时候哈希表的运用就变得必要了起来,作为一个特殊的计数器。先构造一个类似字典的HashMap。然后再每个起点创造一个新的HashMap作为一个特殊的匹配计数器,依据这个计数器的内容和当前匹配的内容维护一个窗口,里面全是符合条件的字符串。起点的个数是字符串数组里字符串的长度,然后按照strstr的 延伸思想逐个匹配,匹配到字典并符合条件的,窗口便扩大,一旦窗口的大小等于L
* L[0].length,便表示找到了符合条件的答案之一。一旦当前子字符串不在字典内,当前维护的窗口便彻底作废。具体看代码吧:
public List<Integer> findSubstring(String S, String[] L) {
HashMap<String, Integer> cached_map = new HashMap<String, Integer>();
List<Integer> res = new LinkedList<Integer>();
if(L == null || L.length == 0)
return res;
int head = 0;
for(String str : L)
cached_map.put(str, cached_map.containsKey(str) ? cached_map.get(str) + 1 : 1);
for(int i = 0; i < L[0].length(); i++){
int counter = 0;
head = i;
HashMap<String, Integer> cur_map = new HashMap<String, Integer>();
for(int j = i; j <= S.length() - L[0].length(); j += L[0].length()){
String tmp_str = S.substring(j, j + L[0].length());
if(cached_map.containsKey(tmp_str)){
if(!cur_map.containsKey(tmp_str) || cur_map.get(tmp_str) < cached_map.get(tmp_str)){
counter++;
cur_map.put(tmp_str, cur_map.containsKey(tmp_str) ? cur_map.get(tmp_str) + 1 : 1);
if(counter == L.length){
res.add(head);
String remove = S.substring(head, head + L[0].length());
cur_map.put(remove, cur_map.get(remove) - 1);
head += L[0].length();
counter--;
}
}else{
String remove_candidate = S.substring(head, head + L[0].length());
while(!remove_candidate.equals(tmp_str)){
cur_map.put(tmp_str, cur_map.get(remove_candidate) - 1);
head += L[0].length();
counter--;
remove_candidate = S.substring(head, head + L[0].length());
}
head += L[0].length();
}
}else{
head = j + L[0].length();
counter = 0;
cur_map.clear();
}
}
}
return res;
}
相关文章推荐
- [Leetcode] Substring with Concatenation of All Words
- LeetCode Substring with Concatenation of All Words
- LeetCode Substring with Concatenation of All Words暴力法暴力法更加暴力的方法
- [LeetCode]Substring with Concatenation of All Words
- LeetCode Online Judge 题目C# 练习 - Substring with Concatenation of All Words
- leetcode 102: Substring with Concatenation of All Words
- [LeetCode] Substring with Concatenation of All Words 解题报告
- LeetCode:Substring with Concatenation of All Words
- leetcode_Substring with Concatenation of All Words
- [LeetCode] Substring with Concatenation of All Words
- LeetCode:Substring with Concatenation of All Words
- [LeetCode] Substring with Concatenation of All Words
- [LeetCode]Substring with Concatenation of All Words
- LeetCode-Substring with Concatenation of All Words
- leetcode 71: Substring with Concatenation of All Words
- LeetCode: Substring with Concatenation of All Words
- LeetCode 笔记系列七 Substring with Concatenation of All Words
- leetcode -- Substring with Concatenation of All Words
- leetcode: Substring with Concatenation of All Words
- LeetCode : Substring with Concatenation of All Words