Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions src/main/java/com/bl/binary_search/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# 704. Binary Search

Difficulty: `Easy`
Topics: `Array`, `Binary Search`

Given an array of integers `nums` which is sorted in ascending order, and an integer `target`, write a function to
search `target` in `nums`. If `target` exists, then return its index. Otherwise, return `-1`.

You must write an algorithm with `O(log n)` runtime complexity.

**Example 1:**

```text
Input: nums = [-1,0,3,5,9,12], target = 9
Output: 4
Explanation: 9 exists in nums and its index is 4
```

**Example 2:**

```text
Input: nums = [-1,0,3,5,9,12], target = 2
Output: -1
Explanation: 2 does not exist in nums so return -1
```

**Constraints:**

- `1 <= nums.length <= 10^4`
- `-10^4 < nums[i], target < 10^4`
- All the integers in `nums` are unique.
- `nums` is sorted in ascending order.
44 changes: 44 additions & 0 deletions src/main/java/com/bl/binary_search/Solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.bl.binary_search;

/**
* This is the solution to the LeetCode problem: 704. Binary Search
*
* @author Børre A. Opedal Lunde
* @since 2024.01.27
*/
public class Solution {

public int search(int[] nums, int target) {

int low = 0;
int high = nums.length - 1;

// The loop will continue until the target is found or the low and high
// indices have crossed each other. In which the target was not found.
while (low <= high) {

// The reason why we don't use (low + high) / 2 is because it can
// cause an integer overflow. For example:
// low = 2 000 000 000
// high = 2 000 000 000
// low + high = 4 000 000 000 which is larger than the maximum
// integer value: 2 147 483 647
final int middleIndex = low + (high - low) / 2;
final int middleValue = nums[middleIndex];

if (middleValue == target) {
// The target was found, return its index.
return middleIndex;
} else if (middleValue > target) {
// The target must be in the left half (lower half) of the array.
high = middleIndex - 1;
} else {
// The target must be in the right half (upper half) of the array.
low = middleIndex + 1;
}
}

// -1 represents that the target was not found.
return - 1;
}
}
103 changes: 103 additions & 0 deletions src/test/java/com/bl/binary_search/SolutionTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package com.bl.binary_search;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
* This is the test to the LeetCode problem: 704. Binary Search
*
* @author Børre A. Opedal Lunde
* @since 2024.01.27
*/
@DisplayName("Binary Search")
class SolutionTest {

private final Solution solution = new Solution();

@Test
@DisplayName("Example one")
void exampleOne() {
int[] nums = {- 1, 0, 3, 5, 9, 12};
int target = 9;

int expected = 4;
int actual = solution.search(nums, target);

assertEquals(expected, actual);
}

@Test
@DisplayName("Example two")
void exampleTwo() {
int[] nums = {- 1, 0, 3, 5, 9, 12};
int target = 2;

int expected = - 1;
int actual = solution.search(nums, target);

assertEquals(expected, actual);
}

@Test
@DisplayName("Empty array should return -1")
void emptyArrayShouldReturn1() {
int[] nums = {};
int target = 9; // Doesn't matter what the target is.

int expected = - 1;
int actual = solution.search(nums, target);

assertEquals(expected, actual);
}

@Test
@DisplayName("Target is a negative number")
void targetIsANegativeNumber() {
int[] nums = {- 1, 0, 3, 5, 9, 12};
int target = - 1;

int expected = 0;
int actual = solution.search(nums, target);

assertEquals(expected, actual);
}

@Test
@DisplayName("Target is larger than the largest number in the array")
void targetIsLargerThanTheLargestNumberInTheArray() {
int[] nums = {- 1, 0, 3, 5, 9, 12};
int target = 13;

int expected = - 1;
int actual = solution.search(nums, target);

assertEquals(expected, actual);
}

@Test
@DisplayName("Target is smaller than the smallest number in the array")
void targetIsSmallerThanTheSmallestNumberInTheArray() {
int[] nums = {- 1, 0, 3, 5, 9, 12};
int target = - 2;

int expected = - 1;
int actual = solution.search(nums, target);

assertEquals(expected, actual);
}

@Test
@DisplayName("All elements in the array are the same")
void allElementsInTheArrayAreTheSame() {
int[] nums = {1, 1, 1, 1, 1, 1};
int target = 1;

int actual = solution.search(nums, target);

// The actual index is not important, as long as it's a valid index.
assertTrue(actual >= 0 && nums[actual] == target);
}
}