Skip to content

Commit 0a4f554

Browse files
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>
1 parent 048bba9 commit 0a4f554

File tree

1 file changed

+61
-17
lines changed

1 file changed

+61
-17
lines changed

src/main/java/com/thealgorithms/misc/RangeInSortedArray.java

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,46 @@
11
package com.thealgorithms.misc;
22

3+
/**
4+
* Utility class for operations to find the range of occurrences of a key
5+
* in a sorted (non-decreasing) array, and to count elements less than or equal to a given key.
6+
*/
37
public final class RangeInSortedArray {
8+
49
private RangeInSortedArray() {
510
}
611

7-
// Get the 1st and last occurrence index of a number 'key' in a non-decreasing array 'nums'
8-
// Gives [-1, -1] in case element doesn't exist in array
12+
/**
13+
* Finds the first and last occurrence indices of the key in a sorted array.
14+
*
15+
* @param nums sorted array of integers (non-decreasing order)
16+
* @param key the target value to search for
17+
* @return int array of size two where
18+
* - index 0 is the first occurrence of key,
19+
* - index 1 is the last occurrence of key,
20+
* or [-1, -1] if the key does not exist in the array.
21+
*/
922
public static int[] sortedRange(int[] nums, int key) {
1023
int[] range = new int[] {-1, -1};
11-
alteredBinSearchIter(nums, key, 0, nums.length - 1, range, true);
12-
alteredBinSearchIter(nums, key, 0, nums.length - 1, range, false);
24+
alteredBinSearchIter(nums, key, 0, nums.length - 1, range, true); // find left boundary
25+
alteredBinSearchIter(nums, key, 0, nums.length - 1, range, false); // find right boundary
1326
return range;
1427
}
1528

16-
// Recursive altered binary search which searches for leftmost as well as rightmost occurrence
17-
// of 'key'
29+
/**
30+
* Recursive altered binary search to find either the leftmost or rightmost occurrence of a key.
31+
*
32+
* @param nums the sorted array
33+
* @param key the target to find
34+
* @param left current left bound in search
35+
* @param right current right bound in search
36+
* @param range array to update with boundaries: range[0] for leftmost, range[1] for rightmost
37+
* @param goLeft if true, searches for leftmost occurrence; if false, for rightmost occurrence
38+
*/
1839
public static void alteredBinSearch(int[] nums, int key, int left, int right, int[] range, boolean goLeft) {
1940
if (left > right) {
2041
return;
2142
}
22-
int mid = (left + right) >>> 1;
43+
int mid = left + ((right - left) >>> 1);
2344
if (nums[mid] > key) {
2445
alteredBinSearch(nums, key, left, mid - 1, range, goLeft);
2546
} else if (nums[mid] < key) {
@@ -41,11 +62,19 @@ public static void alteredBinSearch(int[] nums, int key, int left, int right, in
4162
}
4263
}
4364

44-
// Iterative altered binary search which searches for leftmost as well as rightmost occurrence
45-
// of 'key'
65+
/**
66+
* Iterative altered binary search to find either the leftmost or rightmost occurrence of a key.
67+
*
68+
* @param nums the sorted array
69+
* @param key the target to find
70+
* @param left initial left bound
71+
* @param right initial right bound
72+
* @param range array to update with boundaries: range[0] for leftmost, range[1] for rightmost
73+
* @param goLeft if true, searches for leftmost occurrence; if false, for rightmost occurrence
74+
*/
4675
public static void alteredBinSearchIter(int[] nums, int key, int left, int right, int[] range, boolean goLeft) {
4776
while (left <= right) {
48-
final int mid = (left + right) >>> 1;
77+
int mid = left + ((right - left) >>> 1);
4978
if (nums[mid] > key) {
5079
right = mid - 1;
5180
} else if (nums[mid] < key) {
@@ -55,33 +84,48 @@ public static void alteredBinSearchIter(int[] nums, int key, int left, int right
5584
if (mid == 0 || nums[mid - 1] != key) {
5685
range[0] = mid;
5786
return;
58-
} else {
59-
right = mid - 1;
6087
}
88+
right = mid - 1;
6189
} else {
6290
if (mid == nums.length - 1 || nums[mid + 1] != key) {
6391
range[1] = mid;
6492
return;
65-
} else {
66-
left = mid + 1;
6793
}
94+
left = mid + 1;
6895
}
6996
}
7097
}
7198
}
7299

100+
/**
101+
* Counts the number of elements strictly less than the given key.
102+
*
103+
* @param nums sorted array
104+
* @param key the key to compare
105+
* @return the count of elements less than the key
106+
*/
73107
public static int getCountLessThan(int[] nums, int key) {
74108
return getLessThan(nums, key, 0, nums.length - 1);
75109
}
76110

111+
/**
112+
* Helper method using binary search to count elements less than or equal to the key.
113+
*
114+
* @param nums sorted array
115+
* @param key the key to compare
116+
* @param left current left bound
117+
* @param right current right bound
118+
* @return count of elements less than or equal to the key
119+
*/
77120
public static int getLessThan(int[] nums, int key, int left, int right) {
78121
int count = 0;
79122
while (left <= right) {
80-
final int mid = (left + right) >>> 1;
123+
int mid = left + ((right - left) >>> 1);
81124
if (nums[mid] > key) {
82125
right = mid - 1;
83-
} else if (nums[mid] <= key) {
84-
count = mid + 1; // At least mid+1 elements exist which are <= key
126+
} else {
127+
// nums[mid] <= key
128+
count = mid + 1; // all elements from 0 to mid inclusive are <= key
85129
left = mid + 1;
86130
}
87131
}

0 commit comments

Comments
 (0)