30. Substring with Concatenation of All Words
2016-07-18 16:55
281 查看
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:
words:
You should return the indices:
(order does not matter).
做法挺暴力的,就是一个个位置扫,检查从每个位置开始是否包含了words集合里面的所有串刚好一边。
整体可以用hash加速,字串匹配可以上Boyer-Moore
public class Solution {
public List<Integer> findSubstring(String s, String[] words)
{
List<Integer> arraylist=new ArrayList<>();
if(s.length()==0)
{
for(String word : words)
if(word.length()>0)
return arraylist;
arraylist.add(0);
return arraylist;
}
int wordlen=words[0].length();
int size=words.length;
int R = 128;
int[][] right=new int[size][R];
for(int i=0;i<size;i++)
for (int c = 0; c < R; c++)
right[i][c] = -1;
for(int i=0;i<size;i++)
for (int j = 0; j < words[i].length(); j++)
right[i][words[i].charAt(j)] = j;
HashSet<Integer> hashset=new HashSet<>(20000);
HashSet<Integer> matchhashset=new HashSet<>(6000);
L1: for(int i=0;i+size*wordlen<=s.length();i++)
{
String checknow=s.substring(i, i+size*wordlen);
int hash=checknow.hashCode();
if(!hashset.contains(hash))
hashset.add(hash);
else {
if(matchhashset.contains(hash))
arraylist.add(i);
continue;
}
boolean[] find=new boolean[size];
for(int j=1;j<=size;j++)
{
int start=i+(j-1)*wordlen;
int end=i+j*wordlen;
String sub=s.substring(start, end);
boolean success=false;
for(int m=0;m<size;m++)
if(!find[m])
{
if(search(sub, words[m], right[m])==true)
{
find[m]=true;
success=true;
break;
}
}
if(!success)
continue L1;
}
arraylist.add(i);
matchhashset.add(hash);
}
for(String word:words)
{
if(word.length()>0)
return arraylist;
}
arraylist.add(s.length());
return arraylist;
}
public boolean search(String txt,String pat,int[] right)
{
int M = pat.length();
int N = txt.length();
int skip;
for (int i = 0; i <= N - M; i += skip)
{
skip = 0;
for (int j = M - 1; j >= 0; j--)
if (pat.charAt(j) != txt.charAt(i + j))
{
skip = j - right[txt.charAt(i + j)];
if (skip < 1)
skip = 1;
break;
}
if (skip == 0)
return true;
}
return false;
}
}
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集合里面的所有串刚好一边。
整体可以用hash加速,字串匹配可以上Boyer-Moore
public class Solution {
public List<Integer> findSubstring(String s, String[] words)
{
List<Integer> arraylist=new ArrayList<>();
if(s.length()==0)
{
for(String word : words)
if(word.length()>0)
return arraylist;
arraylist.add(0);
return arraylist;
}
int wordlen=words[0].length();
int size=words.length;
int R = 128;
int[][] right=new int[size][R];
for(int i=0;i<size;i++)
for (int c = 0; c < R; c++)
right[i][c] = -1;
for(int i=0;i<size;i++)
for (int j = 0; j < words[i].length(); j++)
right[i][words[i].charAt(j)] = j;
HashSet<Integer> hashset=new HashSet<>(20000);
HashSet<Integer> matchhashset=new HashSet<>(6000);
L1: for(int i=0;i+size*wordlen<=s.length();i++)
{
String checknow=s.substring(i, i+size*wordlen);
int hash=checknow.hashCode();
if(!hashset.contains(hash))
hashset.add(hash);
else {
if(matchhashset.contains(hash))
arraylist.add(i);
continue;
}
boolean[] find=new boolean[size];
for(int j=1;j<=size;j++)
{
int start=i+(j-1)*wordlen;
int end=i+j*wordlen;
String sub=s.substring(start, end);
boolean success=false;
for(int m=0;m<size;m++)
if(!find[m])
{
if(search(sub, words[m], right[m])==true)
{
find[m]=true;
success=true;
break;
}
}
if(!success)
continue L1;
}
arraylist.add(i);
matchhashset.add(hash);
}
for(String word:words)
{
if(word.length()>0)
return arraylist;
}
arraylist.add(s.length());
return arraylist;
}
public boolean search(String txt,String pat,int[] right)
{
int M = pat.length();
int N = txt.length();
int skip;
for (int i = 0; i <= N - M; i += skip)
{
skip = 0;
for (int j = M - 1; j >= 0; j--)
if (pat.charAt(j) != txt.charAt(i + j))
{
skip = j - right[txt.charAt(i + j)];
if (skip < 1)
skip = 1;
break;
}
if (skip == 0)
return true;
}
return false;
}
}
相关文章推荐
- 线程死锁
- windows关闭端口
- pool(二)——动手入门
- 常见网站系统后台配置smtp发送邮件
- SpringMVC使用注解实现登录
- 分布式消息队列(1)
- 集合(Collection)使用笔记
- SQL------- DATEADD函数
- 多线程概述
- 字节码指令简介
- CI中result() 方法和result_array()方法
- 网站经常出现的错误代码对照表
- 自己动手写word2vec (四):CBOW和skip-gram模型
- hdu2222 ac自动机裸题
- devexpress破解方法
- xStream完美转换XML、JSON
- Discuz提速优化技巧
- Play with docker 1.12
- IMP-00058: ORACLE error 12560 encountered
- Android签名机制及PMS中校验签名