package com.interview.algorithms.string; import java.util.ArrayList; import java.util.List; import java.util.HashMap; import java.util.Map; /** * Created_By: stefanie * Date: 14-7-6 * Time: 下午7:22 * * Given that you have one string of length N and M small strings of length L. * How do you efficiently find the occurrence of each small string in the larger one? * * Solution * 1. only one long string N, and several small string M, so build a index of N, store all the character occurrence location * 2. for every small string, find the location of the 1st char and check if it's following str is matched or not. * * Time: O(N+M*L) Space: O(N) */ public class C11_5_OccurrenceFinder { public static int[] find(String base, String[] list){ Map<Character, List<Integer>> index = buildIndex(base); int[] result = new int[list.length]; for(int i = 0; i < list.length; i++){ String str = list[i]; result[i] = find(index, base, str); } return result; } private static int find(Map<Character, List<Integer>> index, String base, String str){ Character ch = str.charAt(0); for(Integer offset: index.get(ch)){ int i = 1; int j = offset + 1; for(;i < str.length() && j < base.length() && base.charAt(j++) == str.charAt(i++);){} if(i == str.length()) return offset; } return -1; } private static Map<Character, List<Integer>> buildIndex(String base){ Map<Character, List<Integer>> index = new HashMap<Character, List<Integer>>(); for(int i = 0; i < base.length(); i++){ Character ch = base.charAt(i); if(index.get(ch) == null){ index.put(ch, new ArrayList<Integer>()); } index.get(ch).add(i); } return index; } }