Skip to content

Commit dc0ddb8

Browse files
author
Chris Pilcher
committed
Adding algorithm that lets you find both the minimum and maximum at the same time but doing only 3 comparisons for every 2 items
1 parent 3b7dc01 commit dc0ddb8

File tree

3 files changed

+130
-5
lines changed

3 files changed

+130
-5
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
func minimumMaximum<T: Comparable>(var array: [T]) -> (minimum: T, maximum: T)
2+
{
3+
var minimum = array.first!
4+
var maximum = array.first!
5+
6+
let hasOddNumberOfItems = array.count % 2 != 0
7+
if hasOddNumberOfItems {
8+
array.removeFirst()
9+
}
10+
11+
while !array.isEmpty {
12+
let pair = (array.removeFirst(), array.removeFirst())
13+
14+
if pair.0 > pair.1 {
15+
if pair.0 > maximum {
16+
maximum = pair.0
17+
}
18+
if pair.1 < minimum {
19+
minimum = pair.1
20+
}
21+
} else {
22+
if pair.1 > maximum {
23+
maximum = pair.1
24+
}
25+
if pair.0 < minimum {
26+
minimum = pair.0
27+
}
28+
}
29+
}
30+
31+
return (minimum, maximum)
32+
}

Select Minimum Maximum/README.markdown

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ Goal: Find the minimum/maximum object in an unsorted array.
44

55
We have an array of generic objects and we iterate over all the objects keeping track of the minimum/maximum element so far.
66

7-
### An example
7+
### Maximum or minimum
8+
9+
#### An example
810

911
Let's say the we want to find the maximum value in the unsorted list `[ 8, 3, 9, 4, 6 ]`.
1012

@@ -14,9 +16,9 @@ Pick the next number from the list, `3`, and compare it to the current maximum `
1416

1517
Pick the next number from the list, `9`, and compare it to the current maximum `8`. `9` is greater than `8` so we store `9` as the maximum.
1618

17-
Repeat this process until the all items in the list have been processed.
19+
Repeat this process until the all elements in the list have been processed.
1820

19-
### The code
21+
#### The code
2022

2123
Here is a simple implementation in Swift:
2224

@@ -46,9 +48,59 @@ minimum(array) // This will return 3
4648
maximum(array) // This will return 9
4749
```
4850

51+
### Maximum and minimum
52+
53+
To find both the maximum and minimum values contained in array while minimizing the number of comparisons we can compare the items in pairs.
54+
55+
```swift
56+
func minimumMaximum<T: Comparable>(var array: [T]) -> (minimum: T, maximum: T)
57+
{
58+
var minimum = array.first!
59+
var maximum = array.first!
60+
61+
let hasOddNumberOfItems = array.count % 2 != 0
62+
if hasOddNumberOfItems {
63+
array.removeFirst()
64+
}
65+
66+
while !array.isEmpty {
67+
let pair = (array.removeFirst(), array.removeFirst())
68+
69+
if pair.0 > pair.1 {
70+
if pair.0 > maximum {
71+
maximum = pair.0
72+
}
73+
if pair.1 < minimum {
74+
minimum = pair.1
75+
}
76+
} else {
77+
if pair.1 > maximum {
78+
maximum = pair.1
79+
}
80+
if pair.0 < minimum {
81+
minimum = pair.0
82+
}
83+
}
84+
}
85+
86+
return (minimum, maximum)
87+
}
88+
```
89+
90+
Put this code in a playground and test it like so:
91+
92+
```swift
93+
94+
let result = minimumMaximum(array)
95+
result.minimum // This will return 3
96+
result.maximum // This will return 9
97+
```
98+
99+
By picking elements in pairs and comparing their maximum and minimum with the running minimum and maximum we reduce the number of comparisons to 3 for every 2 elements.
100+
49101
### Performance
50102

51-
The algorithm runs at **O(n)**. It compares each object in the array with the running minimum/maximum so the time it takes is proportional to the array length.
103+
These algorithms run at **O(n)**. Each object in the array is compared with the running minimum/maximum so the time it takes is proportional to the array length.
52104

53105
### Swift library
54106

Select Minimum Maximum/SelectMinimumMaximum.playground/Contents.swift

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// Compare each item to find minimum
12
func minimum<T: Comparable>(var array: [T]) -> T? {
23
var minimum = array.removeFirst()
34
for element in array {
@@ -6,6 +7,7 @@ func minimum<T: Comparable>(var array: [T]) -> T? {
67
return minimum
78
}
89

10+
// Compare each item to find maximum
911
func maximum<T: Comparable>(var array: [T]) -> T? {
1012
var maximum = array.removeFirst()
1113
for element in array {
@@ -14,11 +16,50 @@ func maximum<T: Comparable>(var array: [T]) -> T? {
1416
return maximum
1517
}
1618

17-
// Simple test of minimum and maximum functions
19+
// Compare in pairs to find minimum and maximum
20+
func minimumMaximum<T: Comparable>(var array: [T]) -> (minimum: T, maximum: T)
21+
{
22+
var minimum = array.first!
23+
var maximum = array.first!
24+
25+
let hasOddNumberOfItems = array.count % 2 != 0
26+
if hasOddNumberOfItems {
27+
array.removeFirst()
28+
}
29+
30+
while !array.isEmpty {
31+
let pair = (array.removeFirst(), array.removeFirst())
32+
33+
if pair.0 > pair.1 {
34+
if pair.0 > maximum {
35+
maximum = pair.0
36+
}
37+
if pair.1 < minimum {
38+
minimum = pair.1
39+
}
40+
} else {
41+
if pair.1 > maximum {
42+
maximum = pair.1
43+
}
44+
if pair.0 < minimum {
45+
minimum = pair.0
46+
}
47+
}
48+
}
49+
50+
return (minimum, maximum)
51+
}
52+
53+
// Test of minimum and maximum functions
1854
let array = [ 8, 3, 9, 4, 6 ]
1955
minimum(array)
2056
maximum(array)
2157

58+
// Test of minimumMaximum function
59+
let result = minimumMaximum(array)
60+
result.minimum
61+
result.maximum
62+
2263
// Built-in Swift functions
2364
array.minElement()
2465
array.maxElement()

0 commit comments

Comments
 (0)