First strictly smaller element in a sorted array in Java
Last Updated :
23 Feb, 2023
Given a sorted array and a target value, find the first element that is strictly smaller than the given element.
Examples:
Input : arr[] = {1, 2, 3, 5, 8, 12}
Target = 5
Output : 2 (Index of 3)
Input : {1, 2, 3, 5, 8, 12}
Target = 8
Output : 3 (Index of 5)
Input : {1, 2, 3, 5, 8, 12}
Target = 15
Output : 5 (Index of 12)
Input : {1, 2, 3, 5, 8, 12}
Target = 1
Output : -1
Input : {1}
Target = 1
Output : -1
Input : { }
Target = 1
Output : -1
A simple solution is to linearly traverse given array and find first element that is strictly greater. If no such element exists, then return -1.
Below is the implementation for the above approach:
C++
#include <bits/stdc++.h>
int findFirstStrictlySmaller( const std::vector< int >& arr,
int x)
{
for ( int i = arr.size() - 1; i >= 0; i--) {
if (arr[i] < x) {
return i;
}
}
return -1;
}
int main()
{
int x, index;
std::vector< int > arr1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
x = 6;
index = findFirstStrictlySmaller(arr1, x);
std::cout << index << std::endl;
std::vector< int > arr2 = { 1 };
x = 1;
index = findFirstStrictlySmaller(arr2, x);
std::cout << index << std::endl;
std::vector< int > arr3;
x = 1;
index = findFirstStrictlySmaller(arr3, x);
std::cout << index << std::endl;
return 0;
}
|
Java
public class GFG {
public static int findLastStrictlySmaller( int [] arr,
int x)
{
for ( int i = arr.length - 1 ; i >= 0 ; i--) {
if (arr[i] < x) {
return i;
}
}
return - 1 ;
}
public static void main(String[] args)
{
int x, index;
int [] arr1 = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 };
x = 6 ;
index = findLastStrictlySmaller(arr1, x);
System.out.println(index);
int [] arr2 = { 1 };
x = 1 ;
index = findLastStrictlySmaller(arr2, x);
System.out.println(index);
int [] arr3 = {};
x = 1 ;
index = findLastStrictlySmaller(arr3, x);
System.out.println(index);
}
}
|
Python3
def findFirstStrictlySmaller(arr, x):
for i in range ( len (arr) - 1 , - 1 , - 1 ):
if arr[i] < x:
return i
return - 1
arr1 = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]
x = 6
index = findFirstStrictlySmaller(arr1, x)
print (index)
arr2 = [ 1 ]
x = 1
index = findFirstStrictlySmaller(arr2, x)
print (index)
arr3 = []
x = 1
index = findFirstStrictlySmaller(arr3, x)
print (index)
|
C#
using System;
public class GFG {
static int findFirstStrictlySmaller( int [] arr, int x)
{
for ( int i = arr.Length - 1; i >= 0; i--) {
if (arr[i] < x) {
return i;
}
}
return -1;
}
public static void Main()
{
int x, index;
int [] arr1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
x = 6;
index = findFirstStrictlySmaller(arr1, x);
Console.WriteLine(index);
int [] arr2 = { 1 };
x = 1;
index = findFirstStrictlySmaller(arr2, x);
Console.WriteLine(index);
int [] arr3 = {};
x = 1;
index = findFirstStrictlySmaller(arr3, x);
Console.WriteLine(index);
}
}
|
Javascript
function findFirstStrictlySmaller(arr, x){
for (let i = arr.length-1; i>=0; i--){
if (arr[i] < x) return i;
}
return -1;
}
let x, index;
let arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
x = 6;
index = findFirstStrictlySmaller(arr1, x);
console.log(index);
let arr2 = [1];
x = 1;
index = findFirstStrictlySmaller(arr2, x);
console.log(index);
let arr3 = [];
x = 1;
index = findFirstStrictlySmaller(arr3, x);
console.log(index);
|
Time Complexity: O(N), for linear searching a list of N elements.
Auxiliary Space: O(1), because it only uses constant amounts of space for its variables.
An efficient solution is to use Binary Search. In a general binary search, we are looking for a value that appears in the array. Sometimes, however, we need to find the first element which is either greater than a target.
To see that this algorithm is correct, consider each comparison being made. If we find an element that’s greater than the target element, then it and everything above it can’t possibly match, so there’s no need to search that region. We can thus search the left half. If we find an element that is smaller than the element in question, then anything before it must also be larger, so they can’t be the first element that’s smaller and so we don’t need to search them. The middle element is thus the last possible place it could be.
Note that on each iteration we drop off at least half the remaining elements from consideration. If the top branch executes, then the elements in the range [low, (low + high) / 2] are all discarded, causing us to lose floor((low + high) / 2) – low + 1 >= (low + high) / 2 – low = (high – low) / 2 elements.
If the bottom branch executes, then the elements in the range [(low + high) / 2 + 1, high] are all discarded. This loses us high – floor(low + high) / 2 + 1 >= high – (low + high) / 2 = (high – low) / 2 elements.
Consequently, we’ll end up finding the first element smaller than the target in O(lg n) iterations of this process.
Implementation:
C++
#include<bits/stdc++.h>
using namespace std;
int next( int arr[], int target, int end)
{
if (end == 0) return -1;
if (target > arr[end - 1]) return end-1;
int start = 0;
int ans = -1;
while (start <= end)
{
int mid = (start + end) / 2;
if (arr[mid] >= target)
{
end = mid - 1;
}
else
{
ans = mid;
start = mid + 1;
}
}
return ans;
}
int main()
{
int arr[] = { 1, 2, 3, 5, 8, 12 };
int n = sizeof (arr)/ sizeof (arr[0]);
cout << (next(arr, 5, n));
return 0;
}
|
Java
class GfG {
private static int next( int [] arr, int target)
{
int start = 0 , end = arr.length- 1 ;
if (end == 0 ) return - 1 ;
if (target > arr[end]) return end;
int ans = - 1 ;
while (start <= end) {
int mid = (start + end) / 2 ;
if (arr[mid] >= target) {
end = mid - 1 ;
}
else {
ans = mid;
start = mid + 1 ;
}
}
return ans;
}
public static void main(String[] args)
{
int [] arr = { 1 , 2 , 3 , 5 , 8 , 12 };
System.out.println(next(arr, 5 ));
}
}
|
Python3
def next (arr, target):
start = 0 ;
end = len (arr) - 1 ;
if (end = = 0 ):
return - 1 ;
if (target > arr[end]):
return end;
ans = - 1 ;
while (start < = end):
mid = (start + end) / / 2 ;
if (arr[mid] > = target):
end = mid - 1 ;
else :
ans = mid;
start = mid + 1 ;
return ans;
if __name__ = = '__main__' :
arr = [ 1 , 2 , 3 , 5 , 8 , 12 ];
print ( next (arr, 5 ));
|
C#
using System;
class GfG {
private static int next( int [] arr, int target)
{
int start = 0, end = arr.Length-1;
if (end == 0) return -1;
if (target > arr[end]) return end;
int ans = -1;
while (start <= end) {
int mid = (start + end) / 2;
if (arr[mid] >= target) {
end = mid - 1;
}
else {
ans = mid;
start = mid + 1;
}
}
return ans;
}
public static void Main()
{
int [] arr = { 1, 2, 3, 5, 8, 12 };
Console.WriteLine(next(arr, 5));
}
}
|
PHP
<?php
function next0( $arr , $target )
{
$start = 0; $end = sizeof( $arr )-1;
if ( $end == 0) return -1;
if ( $target > $arr [ $end ]) return $end ;
$ans = -1;
while ( $start <= $end )
{
$mid =(int)(( $start + $end ) / 2);
if ( $arr [ $mid ] >= $target )
{
$end = $mid - 1;
}
else
{
$ans = $mid ;
$start = $mid + 1;
}
}
return $ans ;
}
{
$arr = array (1, 2, 3, 5, 8, 12 );
echo (next0( $arr , 5));
}
|
Javascript
<script>
function next(arr, target, end)
{
if (end == 0) return -1;
if (target > arr[end - 1]) return end-1;
let start = 0;
let ans = -1;
while (start <= end)
{
let mid = (start + end) / 2;
if (arr[mid] >= target)
{
end = mid - 1;
}
else
{
ans = mid;
start = mid + 1;
}
}
return ans;
}
let arr = [ 1, 2, 3, 5, 8, 12 ];
let n = arr.length;
console.log(next(arr, 5, n));
</script>
|
Time Complexity: O(log n), Where n is the number of elements in the array.
Auxiliary Space: O(1)
Additional Methods:
1. Iterative binary search: This method is similar to the binary search method I provided earlier, but it uses an iterative approach rather than a recursive one. The basic idea is to use a loop to repeatedly divide the list in half, until the desired element is found or it is clear that the element is not present in the list.
def find_first_strictly_smaller(arr, x):
left = 0
right = len(arr) - 1
result = -1
while left <= right:
mid = left + (right - left) // 2
if arr[mid] < x:
result = mid
left = mid + 1
else:
right = mid - 1
return result
Time Complexity: O(log n), Where n is the number of elements in the array.
Auxiliary Space: O(1)
2. Reverse iterative binary search: This method is similar to the iterative binary search method, but it iterates through the list in reverse order, starting from the last element. This allows it to find the last smaller element in the list, rather than the first one which is first strictly smaller.
def find_first_strictly_smaller(arr, x):
left = 0
right = len(arr) - 1
while left <= right:
mid = right - (right - left) // 2
if arr[mid] < x:
left = mid + 1
else:
right = mid - 1
if right >= 0 and arr[right] < x:
return right
return -1
Time Complexity: O(log n), Where n is the number of elements in the array.
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...