Skip to content

Commit 837934e

Browse files
committed
Merge pull request kodecocodes#22 from chris-pilcher/Select-Minimum-Maximum
Select min and max but doing only 3 comparisons for every 2 items
2 parents ea4532a + 92db225 commit 837934e

File tree

3 files changed

+148
-5
lines changed

3 files changed

+148
-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: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
Goal: Find the minimum/maximum object in an unsorted array.
44

5+
### Maximum or minimum
6+
57
We have an array of generic objects and we iterate over all the objects keeping track of the minimum/maximum element so far.
68

7-
### An example
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,77 @@ 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+
#### An example
56+
57+
Let's say the we want to find the minimum and maximum value in the unsorted list `[ 8, 3, 9, 4, 6 ]`.
58+
59+
Pick the first number, `8`, and store it as the minimum and maximum element so far.
60+
61+
Because we have an odd number of items we remove `8` from the list which leaves the pairs `[ 3, 9 ]` and `[ 4, 6 ]`.
62+
63+
Pick the next pair of numbers from the list, `[ 3, 9 ]`, `3` is less than `9` so we compare `3` to the current minimum `8` and `9` to the current maximum `8`. `3` is less than `8` so the new minimum is `3`. `9` is greater than `8` so the new maximum is `9`.
64+
65+
Pick the next pair of numbers from the list, `[ 4, 6 ]`, `4` is less than `6` so we compare `4` to the current minimum `3` and `6` to the current maximum `9`. `4` is greater than `3` so the minimum does not change. `6` is less than `9` so the maximum does not change.
66+
67+
The result is a minimum of `3` and a maximum of `9`.
68+
69+
#### The code
70+
71+
Here is a simple implementation in Swift:
72+
73+
```swift
74+
func minimumMaximum<T: Comparable>(var array: [T]) -> (minimum: T, maximum: T)
75+
{
76+
var minimum = array.first!
77+
var maximum = array.first!
78+
79+
let hasOddNumberOfItems = array.count % 2 != 0
80+
if hasOddNumberOfItems {
81+
array.removeFirst()
82+
}
83+
84+
while !array.isEmpty {
85+
let pair = (array.removeFirst(), array.removeFirst())
86+
87+
if pair.0 > pair.1 {
88+
if pair.0 > maximum {
89+
maximum = pair.0
90+
}
91+
if pair.1 < minimum {
92+
minimum = pair.1
93+
}
94+
} else {
95+
if pair.1 > maximum {
96+
maximum = pair.1
97+
}
98+
if pair.0 < minimum {
99+
minimum = pair.0
100+
}
101+
}
102+
}
103+
104+
return (minimum, maximum)
105+
}
106+
```
107+
108+
Put this code in a playground and test it like so:
109+
110+
```swift
111+
112+
let result = minimumMaximum(array)
113+
result.minimum // This will return 3
114+
result.maximum // This will return 9
115+
```
116+
117+
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.
118+
49119
### Performance
50120

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.
121+
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.
52122

53123
### Swift library
54124

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)