67 lines
No EOL
3.3 KiB
Text
67 lines
No EOL
3.3 KiB
Text
---
|
|
id: binary-search-sorted
|
|
title: "Binary Search on a Sorted Array"
|
|
author: Siyong Huang, Michael Cao, Nathan Chen
|
|
description: Introduces sorting and binary searching on a sorted array.
|
|
prerequisites:
|
|
- Bronze - Introduction to Data Structures
|
|
frequency: 4
|
|
---
|
|
|
|
import { Problem } from "../models";
|
|
|
|
export const metadata = {
|
|
problems: {
|
|
bubble: [
|
|
new Problem("HR", "Bubble Sort", "https://www.hackerrank.com/challenges/ctci-bubble-sort/problem", "Easy", false, [], "O(N^2)"),
|
|
new Problem("Silver", "Out of Sorts", "834", "Very Hard", false, []),
|
|
],
|
|
count: [
|
|
new Problem("Silver", "Counting Haybales", "666", "Normal", false, []),
|
|
],
|
|
}
|
|
};
|
|
|
|
Suppose that we want to find an element in a sorted array of size $N$ in $O(\log N)$ time. We can do this with [**binary search**](https://en.wikipedia.org/wiki/Binary_search_algorithm); each iteration of the binary search cuts the search space in half, so the algorithm tests $O(\log N)$ values. This is efficient and much better than testing every element in an array.
|
|
|
|
<resources>
|
|
<resource source="KA" title="Binary Search" url="https://www.khanacademy.org/computing/computer-science/algorithms/binary-search/a/binary-search" starred>animations!</resource>
|
|
<resource source="CSA" title="Binary Search" url="binary_search" starred>animation!</resource>
|
|
<resource source="CPH" title="3.3 - Binary Search" starred></resource>
|
|
<resource source="TC" title="Binary Search" url="binary-search"></resource>
|
|
<resource source="GFG" title="Binary Search" url="binary-search"></resource>
|
|
</resources>
|
|
|
|
## Library Functions
|
|
|
|
### C++
|
|
|
|
- [lower_bound](http://www.cplusplus.com/reference/algorithm/lower_bound/)
|
|
- [upper_bound](http://www.cplusplus.com/reference/algorithm/upper_bound/)
|
|
|
|
### Java
|
|
|
|
- [Arrays.binarySearch](https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html)
|
|
- [Collections.binarySearch](https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html)
|
|
|
|
## Coordinate Compression
|
|
|
|
A related topic is **coordinate compression**, which takes some points and reassigns them to remove wasted space.
|
|
|
|
<problems-list problems={metadata.problems.count} />
|
|
|
|
> Farmer John has just arranged his $N$ haybales $(1\le N \le 100,000)$ at various points along the one-dimensional road running across his farm. To make sure they are spaced out appropriately, please help him answer $Q$ queries ($1 \le Q \le 100,000$), each asking for the number of haybales within a specific interval along the road.
|
|
|
|
However, each of the points are in the range $0 \ldots 1,000,000,000$, meaning you can't store locations of haybales in, for instance, a boolean array.
|
|
|
|
<spoiler title="Solution">
|
|
|
|
Let's place all of the locations of the haybales into a list and sort it.
|
|
|
|
(fix part below so transform to range $1\ldots N$)
|
|
|
|
Now, we can map distinct points to smaller integers without gaps. For example, if the haybales existed at positions $[1, 4, 5, 9]$ and queries were $(1, 2)$ and $(4, 6)$, we can place the integers together and map them from $[1, 2, 4, 5, 6, 9] \rightarrow [1, 2, 3, 4, 5, 6]$. This effectively transforms the haybale positions into $[1, 3, 4, 6]$ and the queries into $1, 2$ and $3, 5$.
|
|
|
|
By compressing queries and haybale positions, we've transformed the range of points to $0 \ldots N + 2Q$, allowing us to store prefix sums to effectively query for the number of haybales in a range.
|
|
|
|
</spoiler> |