mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-12-19 07:00:35 +08:00
cleanup: Improve docs, safety, and readability in RangeInSortedArray (#6361)
* cleanup: Improve docs, safety, and readability in RangeInSortedArray * formatting: fix comment formatting issue * formatting: fix array formatting issue --------- Co-authored-by: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
048bba9499
commit
0a4f5542d9
@@ -1,25 +1,46 @@
|
||||
package com.thealgorithms.misc;
|
||||
|
||||
/**
|
||||
* Utility class for operations to find the range of occurrences of a key
|
||||
* in a sorted (non-decreasing) array, and to count elements less than or equal to a given key.
|
||||
*/
|
||||
public final class RangeInSortedArray {
|
||||
|
||||
private RangeInSortedArray() {
|
||||
}
|
||||
|
||||
// Get the 1st and last occurrence index of a number 'key' in a non-decreasing array 'nums'
|
||||
// Gives [-1, -1] in case element doesn't exist in array
|
||||
/**
|
||||
* Finds the first and last occurrence indices of the key in a sorted array.
|
||||
*
|
||||
* @param nums sorted array of integers (non-decreasing order)
|
||||
* @param key the target value to search for
|
||||
* @return int array of size two where
|
||||
* - index 0 is the first occurrence of key,
|
||||
* - index 1 is the last occurrence of key,
|
||||
* or [-1, -1] if the key does not exist in the array.
|
||||
*/
|
||||
public static int[] sortedRange(int[] nums, int key) {
|
||||
int[] range = new int[] {-1, -1};
|
||||
alteredBinSearchIter(nums, key, 0, nums.length - 1, range, true);
|
||||
alteredBinSearchIter(nums, key, 0, nums.length - 1, range, false);
|
||||
alteredBinSearchIter(nums, key, 0, nums.length - 1, range, true); // find left boundary
|
||||
alteredBinSearchIter(nums, key, 0, nums.length - 1, range, false); // find right boundary
|
||||
return range;
|
||||
}
|
||||
|
||||
// Recursive altered binary search which searches for leftmost as well as rightmost occurrence
|
||||
// of 'key'
|
||||
/**
|
||||
* Recursive altered binary search to find either the leftmost or rightmost occurrence of a key.
|
||||
*
|
||||
* @param nums the sorted array
|
||||
* @param key the target to find
|
||||
* @param left current left bound in search
|
||||
* @param right current right bound in search
|
||||
* @param range array to update with boundaries: range[0] for leftmost, range[1] for rightmost
|
||||
* @param goLeft if true, searches for leftmost occurrence; if false, for rightmost occurrence
|
||||
*/
|
||||
public static void alteredBinSearch(int[] nums, int key, int left, int right, int[] range, boolean goLeft) {
|
||||
if (left > right) {
|
||||
return;
|
||||
}
|
||||
int mid = (left + right) >>> 1;
|
||||
int mid = left + ((right - left) >>> 1);
|
||||
if (nums[mid] > key) {
|
||||
alteredBinSearch(nums, key, left, mid - 1, range, goLeft);
|
||||
} else if (nums[mid] < key) {
|
||||
@@ -41,11 +62,19 @@ public final class RangeInSortedArray {
|
||||
}
|
||||
}
|
||||
|
||||
// Iterative altered binary search which searches for leftmost as well as rightmost occurrence
|
||||
// of 'key'
|
||||
/**
|
||||
* Iterative altered binary search to find either the leftmost or rightmost occurrence of a key.
|
||||
*
|
||||
* @param nums the sorted array
|
||||
* @param key the target to find
|
||||
* @param left initial left bound
|
||||
* @param right initial right bound
|
||||
* @param range array to update with boundaries: range[0] for leftmost, range[1] for rightmost
|
||||
* @param goLeft if true, searches for leftmost occurrence; if false, for rightmost occurrence
|
||||
*/
|
||||
public static void alteredBinSearchIter(int[] nums, int key, int left, int right, int[] range, boolean goLeft) {
|
||||
while (left <= right) {
|
||||
final int mid = (left + right) >>> 1;
|
||||
int mid = left + ((right - left) >>> 1);
|
||||
if (nums[mid] > key) {
|
||||
right = mid - 1;
|
||||
} else if (nums[mid] < key) {
|
||||
@@ -55,33 +84,48 @@ public final class RangeInSortedArray {
|
||||
if (mid == 0 || nums[mid - 1] != key) {
|
||||
range[0] = mid;
|
||||
return;
|
||||
} else {
|
||||
right = mid - 1;
|
||||
}
|
||||
right = mid - 1;
|
||||
} else {
|
||||
if (mid == nums.length - 1 || nums[mid + 1] != key) {
|
||||
range[1] = mid;
|
||||
return;
|
||||
} else {
|
||||
left = mid + 1;
|
||||
}
|
||||
left = mid + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of elements strictly less than the given key.
|
||||
*
|
||||
* @param nums sorted array
|
||||
* @param key the key to compare
|
||||
* @return the count of elements less than the key
|
||||
*/
|
||||
public static int getCountLessThan(int[] nums, int key) {
|
||||
return getLessThan(nums, key, 0, nums.length - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method using binary search to count elements less than or equal to the key.
|
||||
*
|
||||
* @param nums sorted array
|
||||
* @param key the key to compare
|
||||
* @param left current left bound
|
||||
* @param right current right bound
|
||||
* @return count of elements less than or equal to the key
|
||||
*/
|
||||
public static int getLessThan(int[] nums, int key, int left, int right) {
|
||||
int count = 0;
|
||||
while (left <= right) {
|
||||
final int mid = (left + right) >>> 1;
|
||||
int mid = left + ((right - left) >>> 1);
|
||||
if (nums[mid] > key) {
|
||||
right = mid - 1;
|
||||
} else if (nums[mid] <= key) {
|
||||
count = mid + 1; // At least mid+1 elements exist which are <= key
|
||||
} else {
|
||||
// nums[mid] <= key
|
||||
count = mid + 1; // all elements from 0 to mid inclusive are <= key
|
||||
left = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user