1
1
package com .thealgorithms .misc ;
2
2
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
+ */
3
7
public final class RangeInSortedArray {
8
+
4
9
private RangeInSortedArray () {
5
10
}
6
11
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
+ */
9
22
public static int [] sortedRange (int [] nums , int key ) {
10
23
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
13
26
return range ;
14
27
}
15
28
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
+ */
18
39
public static void alteredBinSearch (int [] nums , int key , int left , int right , int [] range , boolean goLeft ) {
19
40
if (left > right ) {
20
41
return ;
21
42
}
22
- int mid = ( left + right ) >>> 1 ;
43
+ int mid = left + (( right - left ) >>> 1 ) ;
23
44
if (nums [mid ] > key ) {
24
45
alteredBinSearch (nums , key , left , mid - 1 , range , goLeft );
25
46
} else if (nums [mid ] < key ) {
@@ -41,11 +62,19 @@ public static void alteredBinSearch(int[] nums, int key, int left, int right, in
41
62
}
42
63
}
43
64
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
+ */
46
75
public static void alteredBinSearchIter (int [] nums , int key , int left , int right , int [] range , boolean goLeft ) {
47
76
while (left <= right ) {
48
- final int mid = ( left + right ) >>> 1 ;
77
+ int mid = left + (( right - left ) >>> 1 ) ;
49
78
if (nums [mid ] > key ) {
50
79
right = mid - 1 ;
51
80
} else if (nums [mid ] < key ) {
@@ -55,33 +84,48 @@ public static void alteredBinSearchIter(int[] nums, int key, int left, int right
55
84
if (mid == 0 || nums [mid - 1 ] != key ) {
56
85
range [0 ] = mid ;
57
86
return ;
58
- } else {
59
- right = mid - 1 ;
60
87
}
88
+ right = mid - 1 ;
61
89
} else {
62
90
if (mid == nums .length - 1 || nums [mid + 1 ] != key ) {
63
91
range [1 ] = mid ;
64
92
return ;
65
- } else {
66
- left = mid + 1 ;
67
93
}
94
+ left = mid + 1 ;
68
95
}
69
96
}
70
97
}
71
98
}
72
99
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
+ */
73
107
public static int getCountLessThan (int [] nums , int key ) {
74
108
return getLessThan (nums , key , 0 , nums .length - 1 );
75
109
}
76
110
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
+ */
77
120
public static int getLessThan (int [] nums , int key , int left , int right ) {
78
121
int count = 0 ;
79
122
while (left <= right ) {
80
- final int mid = ( left + right ) >>> 1 ;
123
+ int mid = left + (( right - left ) >>> 1 ) ;
81
124
if (nums [mid ] > key ) {
82
125
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
85
129
left = mid + 1 ;
86
130
}
87
131
}
0 commit comments