您的位置:首页 > 其它

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: 
"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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: