REACTO:
String Search
Prompt
Write a function to find the index of the first appearance of one string (the needle) inside of another (the haystack).
- The function,
indexOf , should take 2 arguments, both of which are strings: "needle" and "haystack" - If needle is in haystack, return the index of the first appearance of the string
- If needle is not in haystack, return -1
Examples
indexOf('or', 'hello world'); // should return 7
indexOf('howdy', 'hello world'); // should return -1
indexOf('oox', 'ooboxoooxo'); // should return 6Naive Approach
const indexOf = (needle, haystack) => {
let counter = 0;
let result = -1;
for (let i = 0; i < haystack.length; i++){
for (let j = 0; j < needle.length; j++){
if (haystack[i + j] === needle[j]) {
counter++;
if (j === 0) result = i;
if (counter === needle.length) return result;
} else {
result = -1;
}
}
}
return result;
};
// Big O
// O(n*m) where n is haystack size and m is needle sizeNaive Approach
const indexOf = (needle, haystack) => {
let counter = 0;
let result = -1;
for (let i = 0; i < haystack.length; i++){
// for each "ith" element of the haystack, loop over the needle and check if
// the element at haystack[i + j] matches needle[j]
for (let j = 0; j < needle.length; j++){
if (haystack[i + j] === needle[j]) {
counter++;
// if the needle has a length of 1, result = index at which it matches in haystack
if (j === 0) result = i;
// if counter = length of the needle, then you know you've accounted for
// all the letters in needle
if (counter === needle.length) return result;
} else {
result = -1; // if needle not found, return -1
}
}
}
return result;
};Optimized Approach
const indexOf2 = (needle, haystack) => {
for (let i = 0; i <= haystack.length - needle.length; i++){
for (let j = 0; j < needle.length; j++){
if (haystack[i + j] !== needle[j]) break;
if (j === needle.length-1) return i;
}
}
return -1;
};
// Big O
// O(n*m) where n is haystack size and m is needle sizeOptimized Approach
const indexOf2 = (needle, haystack) => {
// Loop through the haystack for only as long as the difference
// in length between haystack and needle.
// No point in looping over 'orld' in 'hello world' after the index of 'hello' has been found
// No point in looping over 'orld' in 'hello world' after the index of 'howdy' has NOT been found
for (let i = 0; i <= haystack.length - needle.length; i++){
// 'i' will be 'constant' here, make the haystack
// index dynamic by adding the needle index
for (let j = 0; j < needle.length; j++){
// if the haystack letter doesn't equal needle letter just break out of the loop
// so that 'i' can point to the next starting letter in haystack
if (haystack[i + j] !== needle[j]) break;
// If we're at the last letter of the needle it must mean
// all the other letters matched. Therefore return the 'constant' starting 'i'.
if (j === needle.length-1) return i;
}
}
// if we reach here, it means the needle wasn't found in the haystack.
return -1;
};
Interviewer Tips
- Have your interviewee solve the problem "naively" and then optimize later
- When optimizing, have them think about how they can minimize the number of iterations through each for-loop
- don't need to continue looping through the entire haystack.length when needle.length is x long
- break out of the for-loop when a haystack letter doesn't match a needle letter--don't need to keep looping over the rest of the needle string
String Search
By Fanny Jiang
String Search
- 152