This repository has been archived on 2022-06-22. You can view files and clone it, but cannot push or open issues or pull requests.
usaco-guide/content/3_Bronze/Intro_Sorting.mdx

140 lines
6.2 KiB
Text
Raw Normal View History

2020-06-23 17:27:41 +00:00
---
id: intro-sorting
title: "Introduction to Sorting"
author: Siyong Huang, Michael Cao, Nathan Chen
description: Introduces sorting and binary searching on a sorted array.
2020-06-26 18:29:20 +00:00
frequency: 0
2020-06-23 17:27:41 +00:00
---
2020-06-24 22:31:52 +00:00
import { Problem } from "../models";
export const metadata = {
problems: {
bubble: [
2020-06-29 20:46:39 +00:00
new Problem("HR", "Bubble Sort", "https://www.hackerrank.com/challenges/ctci-bubble-sort/problem", "Easy", false, [], "O(N^2)"),
2020-06-24 22:31:52 +00:00
new Problem("Silver", "Out of Sorts", "834", "Very Hard", false, []),
],
2020-06-29 21:03:24 +00:00
count: [
new Problem("Silver", "Counting Haybales", "666", "Normal", false, []),
],
2020-06-24 22:50:59 +00:00
cses: [
new Problem("CSES", "Apartments", "1084", "Normal", false, [], "Sort applicants and apartments, then greedily assign applicants"),
new Problem("CSES", "Ferris Wheel", "1090", "Normal", false, [], "Sort children, keep a left pointer and a right pointer. Each gondola either is one child from the right pointer or two children, one left and one right."),
new Problem("CSES", "Restaurant Customers", "1619", "Normal", false, [], ""),
new Problem("CSES", "Stick Lengths", "1074", "Normal", false, [], "Spoiler: Optimal length is median"),
],
2020-06-24 22:31:52 +00:00
}
};
2020-06-23 17:27:41 +00:00
**Sorting** is exactly what it sounds like: arranging items in some particular order.
<info-block title="Pro Tip">
2020-06-29 03:13:00 +00:00
No bronze problem should require sorting, but it can be an alternate solution that is sometimes much easier to implement.
2020-06-23 17:27:41 +00:00
</info-block>
## Additional Resources
2020-06-29 20:46:39 +00:00
<resources>
<resource source="CPH" title="3 - Sorting" starred>types of sorting, binary search, C++ code</resource>
</resources>
2020-06-23 17:27:41 +00:00
## Sorting Algorithms
(why are these important?)
There are many sorting algorithms, here are some sources to learn about the popular ones:
2020-06-24 22:31:52 +00:00
### Tutorial
<problems-list problems={metadata.problems.bubble} />
2020-06-23 17:27:41 +00:00
- [HackerEarth Quicksort](https://www.hackerearth.com/practice/algorithms/sorting/quick-sort/tutorial/)
- expected $O(N\log N)$
- [HackerEarth Mergesort](https://www.hackerearth.com/practice/algorithms/sorting/merge-sort/tutorial/)
- $O(N\log N)$
2020-06-29 21:03:24 +00:00
## Library Functions - Sorting
2020-06-23 17:27:41 +00:00
- C++
2020-06-29 21:03:24 +00:00
- [std::sort](https://en.cppreference.com/w/cpp/algorithm/sort)
- [std::stable\_sort](http://www.cplusplus.com/reference/algorithm/stable_sort/)
2020-06-23 17:27:41 +00:00
- [Golovanov399 - C++ Tricks](https://codeforces.com/blog/entry/74684)
- first two related to sorting
- Java
2020-06-29 21:03:24 +00:00
- [Arrays.sort](https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#sort(java.lang.Object[]))
- [Collections.sort](https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#sort(java.util.List))
2020-06-23 17:27:41 +00:00
- Python
2020-06-29 21:03:24 +00:00
- [Sorting Basics](https://docs.python.org/3/howto/sorting.html)
2020-06-23 17:27:41 +00:00
2020-06-29 20:46:39 +00:00
<info-block title="For Users of Java">
The `Arrays.sort()` function uses quicksort on primitive data types such as `long`s. This is fine for USACO, but in other contests such as CodeForces, it may time out on test cases specifically engineered to trigger worst-case $O(N^2)$ behavior in quicksort. See [here](https://codeforces.com/contest/1324/hacks/625031/) for an example of a solution that was hacked on CF.
Two ways to avoid this:
- Declare the underlying array as an array of objects, for example `Long` instead of `long`. This forces the `Arrays.sort()` function to use mergesort, which is always $O(N \log N)$.
- [Shuffle](https://pastebin.com/k6gCRJDv) the array beforehand.
</info-block>
2020-06-23 17:27:41 +00:00
## Binary Search
2020-07-04 06:15:40 +00:00
[Binary search](https://en.wikipedia.org/wiki/Binary_search_algorithm) can be used on monotonic (\*what's that?) functions for a logarithmic runtime.
\*monotonic means *nondecreasing* or *nonincreasing*
2020-06-23 17:27:41 +00:00
Here is a very basic form of binary search:
> Find an element in a sorted array of size $N$ in $O(\log N)$ time.
Other variations are similar, such as the following:
> Given $K$, find the largest element less than $K$ in a sorted array.
### Tutorial
2020-06-29 03:13:00 +00:00
<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>
2020-06-23 17:27:41 +00:00
2020-06-29 21:03:24 +00:00
### Library Functions - Binary Search
#### C++
- [lower_bound](http://www.cplusplus.com/reference/algorithm/lower_bound/)
- [upper_bound](http://www.cplusplus.com/reference/algorithm/upper_bound/)
2020-06-23 17:27:41 +00:00
#### 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)
2020-06-29 21:03:24 +00:00
## Coordinate Compression
2020-06-23 17:27:41 +00:00
2020-06-29 21:03:24 +00:00
Another useful application of sorting is **coordinate compression**, which takes some points and reassigns them to remove wasted space.
2020-06-23 17:27:41 +00:00
2020-06-29 21:03:24 +00:00
<problems-list problems={metadata.problems.count} />
2020-06-23 17:27:41 +00:00
> 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.
2020-06-29 21:03:24 +00:00
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.
### Solution
Let's place all of the locations of the haybales into a list and sort it.
2020-06-23 17:27:41 +00:00
2020-06-29 21:03:24 +00:00
(fix part below so transform to range $1\ldots N$)
2020-06-23 17:27:41 +00:00
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$.
2020-06-24 22:50:59 +00:00
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.
## Problems
2020-06-26 18:29:20 +00:00
<problems-list problems={metadata.problems.cses} />