Amazon Interview Question
Software Engineer / DevelopersTeam: Kindle
Country: India
Interview Type: Written Test
Tweak suffix tree(or a trie) and make each leaf to contain a list of starting indexes of individual occurrences of a suffix.
Preprocessing - O(nlogn)
Searching - O(logn)
Space - O(n^2)
So, this is clearly scalable only of very large lengths of the original string and pattern. For smaller lengths, Rabin-Karp, Naive searching work better.
using suffix trees (no tweak needed ).
Preprocessing - O(n)
Searching - O(|P|) --size of pattern
Space - O(n)
Total time = O( |T| + |P| )
..if the Text to be search in is very large , KMP can be used to save extra space needed for suffix tree , but
Preprocessing = O(|p|)
search-time = O(|T| + i*|P|) , where 'i' is for the 'i'th occurrence of P .
space = O(|p|) .
Total time = O ( |T| + (i+1) |P| )
public int search_KMP(char[] text, char[] word) {
int m = 0, i = 0;
int[] t = table_KMP(text);
while (m + i < text.length) {
if (text[m + i] == word[i]) {
if (i == word.length-1) {
return m;
}
i = i + 1;
} else {
m = m + i - t[i];
if (t[i] > -1)
i = t[i];
else
i = 0;
}
}
return m;
}
public int[] table_KMP(char[] word) {
int t[] = new int[word.length];
t[0] = -1;
t[1] = 0;
int pos = 2, cnd = 0;
while (pos < word.length) {
if (word[pos - 1] == word[cnd]) {
cnd += 1;
t[pos] = cnd;
pos += 1;
} else if (cnd > 0) {
cnd = t[cnd];
} else {
t[pos] = 0;
pos += 1;
}
}
return t;
}
public int occurence(int k,String text, String word){
int i,index = 0,position = 0;
for(i = 0;i<k;i++){
text = text.substring(index);
index = search_KMP(text.toCharArray(),word.toCharArray());
if(i != k-1)
{
index = index +word.length();
}
position = position+index;
}
return position;
}
If complexity is not to be worried about, the following code works for the given question(for all cases).
#include<stdio.h>
#include<string.h>
void searchithoccur(char *pat, char *txt, int location)
{
int m = strlen(pat); int n = strlen(txt);
int array[9];
int count = 0; bool found=0;
for (int i = 0; i <= n-m; i++)
{
int j;
for (j = 0; j < m; j++)
{
if (txt[i+j] != pat[j])
break;
}
if (j == m)
{
array[count]=i;
count++; found = 1;
}
}
if(found==1 && location<count+1) //checking if ith occurrence is there in the text string
found =1;
else found=0;
if(found==1)
printf("for the ith occurrence where i= %d, pattern found at position %d of the text\n",location, array[location-1]);
else if(found==0 ||location>count )
printf("the i=%d occurrence of pattern not found in the text", location);
}
int main()
{
char *text = "abdabcsbbabcsabcbasbbabcbsdabasbabcbsb";
char *pattern = "abc";
int location=2; //ith occurrence of the pattern
searchithoccur(pattern, text, location);
getchar();
return 0;
}
o(n) complexity function in java--
int getPatternIndex(String s, String p,int k){
int count=0;
for(int i=0;i<s.length()-2;i++){
if (s.charAt(i)==p.charAt(0)&&s.charAt(i+1)==p.charAt(1)&&s.charAt(i+2)==p.charAt(2)){
count++;
}
if(count==3){
return i;
}
}
return -1;
}
Java Implementation
Best case O(n) .. Worst case O(nlog n)
private static int occurence(char[] s, char[] ss, int i) {
if (s.length < 1 || ss.length < 1)
return -1;
int index = 0;
for (int j = 0; j < s.length; j++) {
if (s[j] == ss[0]) {
int k = 0;
while (j < s.length && k < ss.length && s[j] == ss[k]) {
j++;
k++;
}
if (k == ss.length)
index++;
else
j -= k-1; //nothing to do restart
if (index == i)
return j - k;
j--;//taking things a back after processing
}
}
return -1;
}
# include<stdio.h>
# include<conio.h>
int main()
{ //0123456789
char *arr ="abcabcefgabc";
char p[4]="abc";char *str = p;
int occur = 1,count=0;
int index=0;
while(*arr)
{
if ((*arr == *str))
{
if(*str == 'c') // last character of array P.
{ count++;str=p;if(count == occur) break;}
++str;
}
else
{
str = p;
}
++arr;
index++;
}
printf("%d",index-2);
getch();
return 0;
}..................o(n)
Use Kmp and keep track of no of occurrence
- NaiveCoder February 25, 2012