Skip to content

Commit 1899d2a

Browse files
15pratikPratik
and
Pratik
authored
Add Upper Bound Search Algorithm (TheAlgorithms#2722)
Co-authored-by: Pratik <pratik.padalia@akridata.com>
1 parent 9b90628 commit 1899d2a

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

Searches/UpperBound.java

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package Searches;
2+
3+
import static java.lang.String.format;
4+
5+
import java.util.Random;
6+
import java.util.concurrent.ThreadLocalRandom;
7+
import java.util.stream.IntStream;
8+
9+
/**
10+
* The UpperBound method is used to return an index pointing to the first element in the range
11+
* [first, last) which has a value greater than val, or the last index if no such element exists
12+
* i.e. the index of the next smallest number just greater than that number. If there are multiple
13+
* values that are equal to val it returns the index of the first such value.
14+
*
15+
* <p>This is an extension of BinarySearch.
16+
*
17+
* <p>Worst-case performance O(log n) Best-case performance O(1) Average performance O(log n)
18+
* Worst-case space complexity O(1)
19+
*
20+
* @author Pratik Padalia (https://github.com/15pratik)
21+
* @see SearchAlgorithm
22+
* @see BinarySearch
23+
*/
24+
class UpperBound implements SearchAlgorithm {
25+
26+
// Driver Program
27+
public static void main(String[] args) {
28+
// Just generate data
29+
Random r = ThreadLocalRandom.current();
30+
31+
int size = 100;
32+
int maxElement = 100000;
33+
34+
Integer[] integers =
35+
IntStream.generate(() -> r.nextInt(maxElement))
36+
.limit(size)
37+
.sorted()
38+
.boxed()
39+
.toArray(Integer[]::new);
40+
41+
// The element for which the upper bound is to be found
42+
int val = integers[r.nextInt(size - 1)] + 1;
43+
44+
UpperBound search = new UpperBound();
45+
int atIndex = search.find(integers, val);
46+
47+
System.out.println(
48+
format(
49+
"Val: %d. Upper Bound Found %d at index %d. An array length %d",
50+
val, integers[atIndex], atIndex, size));
51+
52+
boolean toCheck = integers[atIndex] > val || integers[size - 1] < val;
53+
System.out.println(
54+
format(
55+
"Upper Bound found at an index: %d. Is greater or max element: %b", atIndex, toCheck));
56+
}
57+
58+
/**
59+
* @param array is an array where the UpperBound value is to be found
60+
* @param key is an element for which the UpperBound is to be found
61+
* @param <T> is any comparable type
62+
* @return index of the UpperBound element
63+
*/
64+
@Override
65+
public <T extends Comparable<T>> int find(T[] array, T key) {
66+
return search(array, key, 0, array.length - 1);
67+
}
68+
69+
/**
70+
* This method implements the Generic Binary Search
71+
*
72+
* @param array The array to make the binary search
73+
* @param key The number you are looking for
74+
* @param left The lower bound
75+
* @param right The upper bound
76+
* @return the location of the key
77+
*/
78+
private <T extends Comparable<T>> int search(T[] array, T key, int left, int right) {
79+
if (right <= left) {
80+
return left;
81+
}
82+
83+
// find median
84+
int median = (left + right) >>> 1;
85+
int comp = key.compareTo(array[median]);
86+
87+
if (comp < 0) {
88+
// key is smaller, median position can be a possible solution
89+
return search(array, key, left, median);
90+
} else {
91+
// key we are looking is greater, so we must look on the right of median position
92+
return search(array, key, median + 1, right);
93+
}
94+
}
95+
}

0 commit comments

Comments
 (0)