The Power of Binary Search

luizrebelatto

Luiz Gabriel

Posted on July 1, 2024

The Power of Binary Search

We have the following scenario: We have been given the task of searching for the Product red water bottle in a supermarket stock, in this stock there are 10,000 registered products.


What is Linear Search?

Linear Search

  • It's a simple search algorithm that searches element by element sequentially, with the first element having index 0.
  • Imagine that it takes 1 second to go through each element and the desired product is in position 4,500, this would take 1:15h to find. A totally unfeasible process.
  • In large lists, the cost is higher the maximum number of attempts is equal to the size of the list.
  • execution time O(n) -> Execution time increases linearly with the size of the data input.
import Foundation

func linearSearch(array: [Int], key: Int) -> Int? {
    for index in 0..< array.count {
        if array[index] == key {
            return index
        }
    }
    return nil
}


let numbers = [5, 3, 8, 1, 2, 9, 4, 10 , 11]
if let index = linearSearch(array: numbers, key: 9) {
    print("Item found in the index \(index)")
} else {
    print("Item not found")
}
Enter fullscreen mode Exit fullscreen mode

What is Binary Search?

This data structure has some characteristics such as:

  • To use it, the list must be sorted; if it is not sorted, you can use a sorting algorithm.
  • execution time O(log n) -> n is the number of elements in the list Many frameworks already have this implemented.
  • To calculate the number of attempts, log2(n) is used.
  • The first step is to define the highest point, the lowest point and the middle.

Left = 0 (start of array)

Right = array size minus 1

*Middle = (left + right) / 2 (always integer division)
*

OBSERVATIONS:

  • if left and right meet, the target does not exist in the array

  • if middle > target then right will swap places and go to a position before middle

  • if middle < target then left will swap places and move to a position after middle

  • if the middle is equal to the target, we find the result

Suppose you want to find the number 100 in the array below:
array

Set the initial values of the lower, higher and middle points

left = 0
right = array.count - 1 (7)
middle = (left + right) / 2 (3)
Enter fullscreen mode Exit fullscreen mode

array

Our target is 100, so we compare the middle with the target:

  • middle < target, then we take the left and drag it 1 position in front of the middle
left = 4
right = array.count - 1 (7)
middle = (left + right) / 2 (5)
Enter fullscreen mode Exit fullscreen mode

Image description

  • we'll do the checks and assignments again until we find the target

  • middle == target

left = 5
middle = (left + right) / 2 (6)
right = array.count - 1 (7)
Enter fullscreen mode Exit fullscreen mode

array


When not to use Binary search:

  • List with little data, use linear search to avoid over-engineering

  • If you need to access the data sequentially, it's better to choose another strategy to apply.

  • If the list has a lot of deletions and insertions, it will be difficult to use because you will always need to sort it.

  • Where the data is distributed in several places


Leetcode Example

704. 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:

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

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 <= 104
  • 104 < nums[i], target < 104
  • All the integers in nums are unique.
  • nums is sorted in ascending order.

Answer

func search(_ nums: [Int], _ target: Int) -> Int {
    var left = 0
    var right = nums.count - 1

    // will run until left and right meet
    while left <= right {
        var middle = (right + left) / 2

        if nums[middle] == target {
            return middle
        } else if nums[middle] < target {
            // if middle < target, advance to a position in front of middle
            left = middle + 1
        } else {
            // if middle > target, move to a position behind middle
            right = middle - 1
        }
    }
    // if none is found, return -1 
    return -1
}
Enter fullscreen mode Exit fullscreen mode

List Exercises Leetcode

  • List: Link
  • Repository with my solutions: Link

Contact Me:

💖 💪 🙅 🚩
luizrebelatto
Luiz Gabriel

Posted on July 1, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

The Power of Binary Search
algorithms The Power of Binary Search

July 1, 2024