1. 问题描述:
给定一段产品的英文描述,包含M个单词,每个英文单词以空格分隔,无其他的标点符号
再给定N个英文单词关键字,要找出此产品描述中的包含的N个关键字(每个关键字至少出现一次)的长度最短的子串,作为产品简介输出,请说明思路并变成实现方法
2. 使用两层循环依次扫描,第一层循环变量为i,第二层循环变量为j,那么每一次从i到j,判断i到j之间是否包含所有关键字,这里判断的处理交给一个函数来处理,并且把所有要寻找的关键字放入到map中,其中关键字可能有重复,所以这里要处理单词重复的问题,在整个函数中扫描所有放进map的关键字,看i到j之间的单词是否全部在里面
3. 具体的代码实现如下:
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
solve(new String[]{"a","ab","a","a","b","c","d","h","e","f","f","c","c","d","e","f","d","h","q"},
new String[]{"ab","a"});
}
private static void solve(String[] words, String[] keys) {
int begin = 0,end = 0;
int len = Integer.MAX_VALUE;
for(int j = 1;j<words.length;j++){
for(int i = j-1;i>=0;i--){
if(containsAll(words,keys,i,j)){
if(j-i+1<len){
len = j-i+1;
begin = i;
end = j;
}
}
}
}
print(words,begin,end);
}
private static void print(String[] words, int begin, int end) {
System.out.println(begin+" "+end);
for(int i = begin;i<=end;i++){
System.out.print(words[i]+" ");
}
}
private static boolean containsAll(String[] words, String[] keys, int i, int j) {
Map<String,Integer> map1 = new HashMap<String,Integer>();
for(int k = 0;k<keys.length;k++){
String key = keys[k];
if(map1.get(key)==null)map1.put(key, 1);
else{
//假如关键字有两个重复的字,那么在上一次的基础上加1
map1.put(key, map1.get(key)+1);
}
}
Map<String,Integer> map2 = new HashMap<String,Integer>();
for(int k = i;k<=j;k++){
String key = words[k];
if(map2.get(key)==null)map2.put(key, 1);
else{
//假如关键字有两个重复的字,那么在上一次的基础上加1
map2.put(key, map2.get(key)+1);
}
}
//循环遍历关键在看看i到j是否全部包含
for(Map.Entry<String, Integer>e:map1.entrySet()){
if(map2.get(e.getKey())==null||map2.get(e.getKey())<e.getValue()){
return false;
}
}
return true;
}
}