|
| 1 | +## Purpose |
| 2 | + |
| 3 | +Implement a binary search algorithm that takes a sorted `int` array and some `int` target value and returns the index of the |
| 4 | +target value, if it exists. |
| 5 | + |
| 6 | +## Discussion |
| 7 | + |
| 8 | +The way I thought about implementing a binary search algorithm was the following |
| 9 | + |
| 10 | +1. Given an array of sorted `int` values, pick the first, last, and middle indices (round down if there is an even number of indices). |
| 11 | +2. If the target value equals any of the values at the first/ last / middle index, return that index. |
| 12 | + Else, check to see if the target value is less / greater than the middle index value. |
| 13 | + 1. If it's less than the middle index value, than we can assume that the target value, if it exists, |
| 14 | + is between the first index and the middle index (since the array should be sorted). Thus, we can call our search |
| 15 | + function on this sub-array, specifying a start index of the first index + 1 (since we already checked this) |
| 16 | + and an end index of the middle index - 1 (again, since we already checked this). |
| 17 | + 2. If it's greater than the middle index value, we can assume that the target value is between the middle index and the last index. |
| 18 | + Thus, we can call the search function on this sub-array, specifying a start index of the middle index + 1 and an |
| 19 | + end index of the last index - 1. |
| 20 | +3. We continue this process of analyzing the sub-arrays until our sub-array is empty, in which case a `NoSuchElementException` |
| 21 | + is thrown. |
| 22 | + |
| 23 | + |
| 24 | +Things that I'm unsure about |
| 25 | + |
| 26 | +* Does it make sense to have the `public` `search` method immediately call the `private` `searchSubArray` method? |
| 27 | + The reason I did this is to obfuscate the idea of a `leftIndex` / `rightIndex` from the API user. |
| 28 | +* Does the `NoSuchElementException` make sense? Would returning `-1` make more sense? |
| 29 | +* Any particular thoughts on my use of early returns? |
| 30 | + |
| 31 | +## Implementation |
| 32 | + |
| 33 | + import java.util.NoSuchElementException; |
| 34 | + |
| 35 | + public class BinarySearcher { |
| 36 | + /** |
| 37 | + * Executes a binary search for some target value given an input array of sorted values |
| 38 | + * @param values a sorted array |
| 39 | + * @param target a value to search for |
| 40 | + * @return the index of the target value, if it exists. If the target value does not exist, a NoSuchElementException is thrown. |
| 41 | + */ |
| 42 | + public static int search(int[] values, int target) { |
| 43 | + return searchSubArray(values, 0, values.length - 1, target); |
| 44 | + } |
| 45 | + |
| 46 | + private static int searchSubArray(int[] values, int leftIndex, int rightIndex, int target) { |
| 47 | + if (values.length == 0 || leftIndex < 0 || rightIndex < 0) { |
| 48 | + throw new NoSuchElementException(String.format("Unable to find target: {} in values", target)); |
| 49 | + } |
| 50 | + |
| 51 | + if (target == values[leftIndex]) { |
| 52 | + return leftIndex; |
| 53 | + } |
| 54 | + |
| 55 | + if (target == values[rightIndex]) { |
| 56 | + return rightIndex; |
| 57 | + } |
| 58 | + |
| 59 | + int middleIndex = Double.valueOf(Math.floor((rightIndex - leftIndex) / 2)).intValue(); |
| 60 | + |
| 61 | + int middleValue = values[middleIndex]; |
| 62 | + |
| 63 | + if (target < middleValue) { |
| 64 | + return searchSubArray(values, leftIndex + 1, middleIndex - 1, target); |
| 65 | + } |
| 66 | + |
| 67 | + else if (target > middleValue) { |
| 68 | + return searchSubArray(values, middleIndex + 1, rightIndex - 1, target); |
| 69 | + } |
| 70 | + |
| 71 | + else { |
| 72 | + return middleIndex; |
| 73 | + } |
| 74 | + } |
| 75 | + } |
0 commit comments