题目:Substring with Concatenation of All Words
难度: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 words exactly 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里有【a,a】,那就是找含有aa的子串,如果是【b,a,a】,就是找 aab、aba、baa的子串索引。
一开始,我的思路是先构造一个hashmap,保存words里所有的单词出现的次数。然后找到所有单词在母串中的索引,然后从每个索引开始检测是否符合要求。具体代码如下:
public class h_30_SubstringWithConcatenationOfAllWords {
public List
findSubstring(String s, String[] words) {
ArrayList
list=new ArrayList<>();
ArrayList
index=new ArrayList<>();
if(s==null||words==null) return list;
if(words[0].equals("")) return list;
//文本长度
int textlen=s.length();
//单词长度
int len=words[0].length();
String temp;
int inttemp;
//初始化Hashmap
HashMap
map=getHashMap(words);
//参照表
// System.out.println("参照表");
HashMap
hm=getHashMap(words); clearMap(hm,words); for(String w:words){ hm.put(w, hm.get(w)+1); // System.out.println("word="+w+" value="+hm.get(w)); } //找到每个单词出现的位置 HashMap
word=new HashMap
(); for(int i=0;i
textlen){ continue; } //提取要判断的字符串 temp=s.substring(inttemp, inttemp+words.length*len); //判断temp里是不是不重复地包含了所有字符串 if(isAllcontained(map,hm,temp,words)){ list.add(inttemp); } clearMap(map,words); } return list; } public HashMap
getHashMap(String[] words){ HashMap
map=new HashMap<>(); for(int i=0;i
map,String[] words){ for(int i=0;i
map,HashMap
hm,String s,String[] words){ // System.out.println("str="+s); int len=words[0].length(); String temp; for(int i=0;i
list=s.findSubstring("111hahzzpzzphah111",words); System.out.println("--------------"); for(int i=0;i
但是,运行显示超时,经过分析,我觉得是对hashmap的操作才复杂,用到了多个表进行对比,为此,我重新参考了NearXDJ的文章,觉得去除“找到所有单词在母串中的索引”这一步骤,直接对母串从I=0开始遍历检查是否满足条件。不过运行时间依然不通过~经过优化,我将循环中的String的构造拿了出来,这才使时间勉强通过~
具体代码如下:
public class Solution {
public List
findSubstring(String s, String[] words) {
String temp=new String();
ArrayList
res=new ArrayList
();
if(s.equals("")||words==null){ //为空时
return res;
}
int slen=s.length(); //母串长度
int wordlen=words[0].length(); //子串长度
int wordCount=words.length; //单词长度
int sublen=wordlen*wordCount; //每次需要从母串中拿来进行匹配的子串的长度
HashMap
mywords=new HashMap
(); int i,j,k; for(i=0;i
tempMap=new HashMap
(mywords); count=0; int subCount=i+sublen; //临时保存母串中需要拿出来匹配的长度 k=i; while(k
0){ tempMap.put(temp, tempMap.get(temp)-1);//将用过的单词剔除 k=k+wordlen; count++; }else{ //虽然找到,但是多余了,也要剔除 i++; break; } } if(count==wordCount){ res.add(i); tempMap.clear(); i++; } } } return res; } }
自己的代码在所有的submit中只处于中下的运行时间,觉得还有很多可以优化的地方,不过本人技术很差,故将代码奉上,希望大家提出宝贵的意见哈!