I needed a function to find the first and last indices into a sorted list corresponding to a given value (roughly similar to C++'s equal_range()
).
This is the solution I came up with:
function findSol(target, arr){
var i, len, first_found, first_i, last_i;
first_i = -1;
last_i = -1;
first_found = false;
for(i = 0, len = arr.length; i<len; i++){
if(arr[i] !== target){
if(first_found){
break;
}else{
continue;
}
}
if(!first_found){
first_i = i;
first_found = true;
}
last_i = i;
}
return [first_i, last_i];
}
var arr = [1, 1, 2, 2, 2, 2, 3, 4, 6, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 15, 15, 16, 18, 20, 20, 22];
console.log(findSol(1, arr));//[0, 1]
console.log(findSol(2, arr));//[2, 5]
console.log(findSol(4, arr));//[7, 7]
console.log(findSol(5, arr));//[-1, -1]
console.log(findSol(22, arr));//[25, 25]
Youtuber approach:
def first_and_last(arr, target): for i in range(len(arr)): if arr[i] == target: start = i while i+1 < len(arr) and arr[i+1] == target: i += 1 return [start, i] return [-1, -1]
(about min 7:00 into this video about solutions to interview questions by Inside code)
So while I dislike a loop within a loop, his solution can be improved for readability by maybe having two back to back loops, the 2nd loop only starting if a match was found on the 1st loop, but still I think this would be overcomplicated no?
What I fail to see is if my solution is worse, I've lately been doing a lot of placing the continue
at the very beginning and maybe that's hard to see what's going on, but in this case I think it's self explanatory:
Not the target? Ok then let's see if there was a match already, if yes then the consecutive streak just finished so we exit, if no then skip and keep looking for a match.
Any thoughts?
.indexOf()
and.lastIndexOf()
built in? \$\endgroup\$