javaintermediate
Binary Search — Lower Bound, Upper Bound, and Rotated Array
Binary search variants: lower/upper bound, search in rotated sorted array, and finding peaks.
javaPress ⌘/Ctrl + Shift + C to copy
import java.util.Arrays;
public class BinarySearchVariants {
// Standard binary search
static int binarySearch(int[] arr, int target) {
int lo = 0, hi = arr.length - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (arr[mid] == target) return mid;
else if (arr[mid] < target) lo = mid + 1;
else hi = mid - 1;
}
return -1;
}
// Lower bound — first index where arr[i] >= target
static int lowerBound(int[] arr, int target) {
int lo = 0, hi = arr.length;
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (arr[mid] < target) lo = mid + 1;
else hi = mid;
}
return lo;
}
// Upper bound — first index where arr[i] > target
static int upperBound(int[] arr, int target) {
int lo = 0, hi = arr.length;
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (arr[mid] <= target) lo = mid + 1;
else hi = mid;
}
return lo;
}
// Count occurrences of target
static int count(int[] arr, int target) {
return upperBound(arr, target) - lowerBound(arr, target);
}
// Search in rotated sorted array
static int searchRotated(int[] arr, int target) {
int lo = 0, hi = arr.length - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (arr[mid] == target) return mid;
if (arr[lo] <= arr[mid]) { // left half sorted
if (target >= arr[lo] && target < arr[mid]) hi = mid - 1;
else lo = mid + 1;
} else { // right half sorted
if (target > arr[mid] && target <= arr[hi]) lo = mid + 1;
else hi = mid - 1;
}
}
return -1;
}
// Find peak element
static int findPeak(int[] arr) {
int lo = 0, hi = arr.length - 1;
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (arr[mid] < arr[mid + 1]) lo = mid + 1;
else hi = mid;
}
return lo;
}
// Binary search on answer (minimum capacity to ship within D days)
static int shipWithinDays(int[] weights, int days) {
int lo = Arrays.stream(weights).max().orElse(0);
int hi = Arrays.stream(weights).sum();
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
int needed = 1, current = 0;
for (int w : weights) {
if (current + w > mid) { needed++; current = 0; }
current += w;
}
if (needed <= days) hi = mid;
else lo = mid + 1;
}
return lo;
}
public static void main(String[] args) {
int[] sorted = {1, 2, 2, 2, 3, 5, 8, 13};
System.out.println("Search 2: " + binarySearch(sorted, 2));
System.out.println("Lower bound 2: " + lowerBound(sorted, 2)); // 1
System.out.println("Upper bound 2: " + upperBound(sorted, 2)); // 4
System.out.println("Count of 2: " + count(sorted, 2)); // 3
int[] rotated = {4, 5, 6, 7, 0, 1, 2};
System.out.println("Rotated search 0: " + searchRotated(rotated, 0)); // 4
int[] peaks = {1, 3, 5, 4, 2};
System.out.println("Peak at: " + findPeak(peaks)); // 2
int[] weights = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
System.out.println("Min capacity for 5 days: " + shipWithinDays(weights, 5)); // 15
}
}Use Cases
- Efficient search in sorted datasets
- Range queries and counting occurrences
- Interview preparation for algorithm questions
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
javaintermediate
Tree Traversal — DFS and BFS
Implement tree data structure with DFS (pre/in/post order), BFS, and recursive/iterative traversals.
Best for: Tree-based data structure traversal
#java#tree
javaadvanced
Sorting Algorithms — Quick, Merge, and Heap
Implement classic sorting algorithms in Java: quicksort, mergesort, heapsort, and their time complexity.
Best for: Understanding sorting algorithm trade-offs
#java#sorting
javabeginner
HashMap Operations and Patterns
Essential HashMap operations: put, get, merge, compute, getOrDefault, and iteration patterns.
Best for: Counting word frequencies in text
#java#collections
javaintermediate
Java Map — Advanced Operations
Master Map operations: compute, merge, getOrDefault, multi-map, BiMap, and stream-based grouping.
Best for: Aggregation and grouping operations on data
#java#map