Skip to content

Commit dab6def

Browse files
pratikpadaliaPratik
andauthored
Add LowerBound search algorithm (TheAlgorithms#2406)
Co-authored-by: Pratik <pratik.padalia@akridata.com>
1 parent 9b38ecd commit dab6def

1 file changed

Lines changed: 97 additions & 0 deletions

File tree

Searches/LowerBound.java

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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 LowerBound method is used to return an index pointing to the first element in the range
11+
* [first, last) which has a value not less than val, i.e. the index of the next smallest number
12+
* just greater than or equal to that number. If there are multiple values that are equal to val it
13+
* 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 LowerBound 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 lower bound is to be found
42+
int val = integers[r.nextInt(size - 1)] + 1;
43+
44+
LowerBound search = new LowerBound();
45+
int atIndex = search.find(integers, val);
46+
47+
System.out.println(
48+
format(
49+
"Val: %d. Lower 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+
"Lower 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 LowerBound value is to be found
60+
* @param key is an element for which the LowerBound is to be found
61+
* @param <T> is any comparable type
62+
* @return index of the LowerBound 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+
return median;
89+
} else if (comp < 0) {
90+
// median position can be a possible solution
91+
return search(array, key, left, median);
92+
} else {
93+
// key we are looking is greater, so we must look on the right of median position
94+
return search(array, key, median + 1, right);
95+
}
96+
}
97+
}

0 commit comments

Comments
 (0)