Given a sorted array of size n, find the number of elements that are less than or equal to a given element and number of elements that are greater than equal to.
Examples :
Input : arr[] = {1, 2, 8, 10, 11, 12, 19} key = 0
Output : 0, 7
Explanation : There are no elements less or equal to 0 and 7 elements greater to 0.Input : arr[] = {1, 5, 8, 12, 12, 12, 19} key = 12
Output : 6, 4
Explanation : There are 6 elements less or equal to 12 and 4 elements greater or equal to 12.
[Naive approach] : Linear Search - O(n) Time and O(1) Space
Iterate over the complete array, count elements that are less than or equal to the target, and derive the count of elements greater than the target from the remaining elements.
using namespace std;
// Simple linear traversal for counting
vector<int> getMoreAndLess(vector<int>& arr, int target)
{
int n = arr.size();
int i = 0;
// count of elements <= target
for (i = 0; i < n; i++) {
// all elements before index i are <= target
if (arr[i] > target)
break;
}
// count of elements >= target
int j = 0;
for (j = 0; j < n; j++) {
// all elements from index j onward are >= target
if (arr[j] >= target)
break;
}
// return {less, greater};
return {i, n - j};
}
// Driver Code
int main()
{
vector<int> arr = { 1, 2, 8, 10, 11, 12, 19 };
int key = 0;
vector<int> res = getMoreAndLess(arr, key);
cout << res[0] << " ";
cout << res[1];
return 0;
}
class GFG {
// Simple linear traversal for counting
static int[] getMoreAndLess(int arr[], int target)
{
// declared a variable to count
int n = arr.length;
int i = 0;
// count of elements <= target
for (i = 0; i < n; i++) {
// break when element greater than target
if (arr[i] > target)
break;
}
// count of elements >= target
int j = 0;
for (j = 0; j < n; j++) {
if (arr[j] >= target) // find first element >= target
break;
}
// return the count
return new int[] { i, n - j };
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 1, 2, 8, 10, 11, 12, 19 };
int key = 0;
int[] res = getMoreAndLess(arr, key);
System.out.print(res[0] + " " + res[1]);
}
}
class GFG :
# Simple linear traversal for counting
@staticmethod
def getMoreAndLess(arr, target) :
# declared a variable to count
n = len(arr)
i = 0
# count of elements <= target
while (i < n) :
# break when element greater than target
if (arr[i] > target) :
break
i += 1
# count of elements >= target
j = 0
while (j < n) :
if(arr[j] >= target) :
break
j += 1
# return the count
return i, n-j
# Driver Code
@staticmethod
def main( args) :
arr = [1, 2, 8, 10, 11, 12, 19]
key = 0
res = GFG.getMoreAndLess(arr, key)
print(res[0], res[1])
if __name__=="__main__":
GFG.main([])
# This code is contributed by aadityaburujwale.
using System;
public class GFG
{
// Simple linear traversal for counting
public static int[] getMoreAndLess(int[] arr, int target)
{
// declared a variable to count
int n = arr.Length;
var i = 0;
// count of elements <= target
for (i = 0; i < n; i++)
{
// break when element greater than target
if (arr[i] > target)
{
break;
}
}
// count of elements >= target
var j = 0;
for (j = 0; j < n; j++)
{
// break when element greater than target
if (arr[j] >= target)
{
break;
}
}
// return the count
return new int[] { i, n - j };
}
// Driver Code
public static void Main(String[] args)
{
int[] arr = {1, 2, 8, 10, 11, 12, 19};
var key = 0;
int[] res = getMoreAndLess(arr, key);
Console.Write(res[0]+" "+res[1]);
}
}
function getMoreAndLess(arr, target)
{
let n = arr.length;
// count of elements <= target
let i = 0;
for (i = 0; i < n; i++) {
// all elements before index i are <= target
if (arr[i] > target)
break;
}
let j = 0;
// count of elements >= target
for (j = 0; j < n; j++) {
// all elements from index j onward are >= target
if (arr[j] >= target)
break;
}
// return the count
return [ i, n - j ];
}
// Driver Code
let arr = [ 1, 2, 8, 10, 11, 12, 19 ];
let key = 0;
let res = getMoreAndLess(arr, key);
console.log(res[0] +" "+ res[1]);
Output
0 7
[Efficient approach]: Binary Search - O(log n) Time and O(1) Space
As the whole array is sorted we can use binary search to find results.
- Do a Binary Search to find first index where element >= target. In this search, if arr[mid] >= target, we set answer and move to left side to find if there are more elements on the left side. We call this function lowerBound(). For example, if the input array is [1, 3, 4, 4, 4, 6, 7] and target is 4, then this function returns 2.
- Do a Binary Search to find first index where element > target. In this search, if arr[mid] > target, we set answer and move to left side to find if there are more elements on the left side. We call this function upperBound(). For example, if the input array is [1, 3, 4, 4, 4, 6, 7] and target is 4, then this function returns 5.
- The count of smaller or equal elements is equal to the value returned by upperBound(). The count of greater or equal elements is equal to size of array minus the value returned by lowerBound()
#include <bits/stdc++.h>
#include <iostream>
#include <vector>
using namespace std;
// first index where element >= target
int lowerBound(vector<int>& arr, int target)
{
int low = 0, high = arr.size() - 1;
int ans = arr.size();
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] < target) {
low = mid + 1;
} else {
ans = mid;
high = mid - 1;
}
}
return ans;
}
// Find first position where element > target
int upperBound(vector<int>& arr, int target)
{
int low = 0, high = arr.size() - 1;
int ans = arr.size();
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] <= target) {
low = mid + 1;
} else {
ans = mid;
high = mid - 1;
}
}
return ans;
}
// Use lowerBound and upperBound to get both counts
vector<int> getMoreAndLess(vector<int>& arr, int target)
{
int l = lowerBound(arr, target);
int r = upperBound(arr, target);
return {r, (int)arr.size() - l};
}
int main()
{
vector<int> arr = {1, 2, 8, 10, 11, 12, 19};
int key = 0;
vector<int> res = getMoreAndLess(arr, key);
cout << res[0] << " " << res[1] << "\n";
return 0;
}
class GfG {
// Function to get the count of elements in the array
// which are strictly less than x and strictly more than
// target.
static int[] getMoreAndLess(int[] arr, int target)
{
int l = lowerBound(arr, target);
int r = upperBound(arr, target);
return new int[] { r, arr.length - l };
}
// Find the position where elements are greater than or
// equal to x
static int lowerBound(int[] arr, int target)
{
int low = 0, high = arr.length - 1;
int ans = arr.length;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] < target) {
low = mid + 1;
}
else {
high = mid - 1;
ans = mid;
}
}
return ans;
}
static int upperBound(int[] arr, int target)
{
int low = 0, high = arr.length - 1;
int ans = arr.length;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] <= target) {
low = mid + 1;
}
else {
high = mid - 1;
ans = mid;
}
}
return ans;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 1, 2, 8, 10, 11, 12, 19 };
int key = 0;
int[] res = getMoreAndLess(arr, key);
System.out.println(res[0] + " " + res[1]);
}
}
class GFG:
@staticmethod
def lower_bound(arr, target):
"""
Find the first index where element >= target.
Used to calculate count of elements >= target.
"""
low = 0
high = len(arr) - 1
ans = len(arr) # default: no element >= target found
while low <= high:
mid = low + (high - low) // 2
if arr[mid] < target:
low = mid + 1 # too small, go right
else:
ans = mid # potential answer, keep going left for earlier one
high = mid - 1
return ans
@staticmethod
def upper_bound(arr, target):
low = 0
high = len(arr) - 1
ans = len(arr)
while low <= high:
mid = low + (high - low) // 2
if arr[mid] <= target:
low = mid + 1
else:
ans = mid
high = mid - 1
return ans
@staticmethod
def getMoreAndLess(arr, target):
n = len(arr)
l = GFG.lower_bound(arr, target)
r = GFG.upper_bound(arr, target)
less_equal = r
greater_equal = n - l
return less_equal, greater_equal
@staticmethod
def main(args):
arr = [1, 2, 8, 10, 11, 12, 19]
key = 0
res = GFG.getMoreAndLess(arr, key)
print(res[0], res[1])
if __name__ == "__main__":
GFG.main([])
using System;
class GfG {
// count of element >= target
static int LowerBound(int[] arr, int target)
{
int low = 0;
int high = arr.Length - 1;
int ans = arr.Length;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] < target) {
low = mid + 1;
}
else {
ans = mid;
high = mid - 1;
}
}
return ans;
}
// count of elements <= target
static int UpperBound(int[] arr, int target)
{
int low = 0;
int high = arr.Length - 1;
int ans = arr.Length;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] <= target) {
low = mid + 1;
}
else {
ans = mid;
high = mid - 1;
}
}
return ans;
}
// Use LowerBound and UpperBound to get both counts
static int[] GetMoreAndLess(int[] arr, int target)
{
int n = arr.Length;
int l = LowerBound(arr, target);
int r = UpperBound(arr, target);
return new int[] { r, n - l };
}
public static void Main(String[] args)
{
int[] arr = { 1, 2, 8, 10, 11, 12, 19 };
int target = 0;
int[] res = GetMoreAndLess(arr, target);
Console.WriteLine(res[0] + " " + res[1]);
}
}
function lowerBound(arr, target)
{
let low = 0;
let high = arr.length - 1;
let ans = arr.length;
// count of elements >= target
while (low <= high) {
let mid = low + Math.floor((high - low) / 2);
if (arr[mid] < target) {
low = mid + 1;
} else {
ans = mid;
high = mid - 1;
}
}
return ans;
}
function upperBound(arr, target)
{
let low = 0;
let high = arr.length - 1;
let ans = arr.length;
// count of elements <= target
while (low <= high) {
let mid = low + Math.floor((high - low) / 2);
if (arr[mid] <= target) {
low = mid + 1;
} else {
ans = mid;
high = mid - 1;
}
}
return ans;
}
// Use lowerBound and upperBound to get both counts
function getMoreAndLess(arr, target)
{
const n = arr.length;
const l = lowerBound(arr, target);
const r = upperBound(arr, target);
return [r, n - l];
}
// Driver code
let arr = [1, 2, 8, 10, 11, 12, 19];
let key = 0;
let res = getMoreAndLess(arr, key);
console.log(res[0] + " " + res[1]);
Output
0 7
Using Library
Another Approach: Using standard in-built library functions such as lower_bound and upper_bound in C++. or bisect_left and bisect_right() in Python.
using namespace std;
vector<int> getMoreAndLess(vector<int> &arr, int target)
{
int n = arr.size();
// first index where element > target
// all elements before this index are <= target
int r = upper_bound(arr.begin(), arr.end(), target) - arr.begin();
// first index where element >= target
// all elements from this index onward are >= target
int l = lower_bound(arr.begin(), arr.end(), target) - arr.begin();
return {r, n - l};
}
// Driver code
int main()
{
vector<int> arr = { 1, 2, 8, 10, 11, 12, 19 };
int key = 0;
vector<int> res = getMoreAndLess(arr, key);
cout << res[0] << " " << res[1];
return 0;
}
from bisect import bisect_left, bisect_right
def getMoreAndLess(arr, target):
n = len(arr)
# first index where element > target
# count of elements <= target
r = bisect_right(arr, target)
# first index where element >= target
# count of elements >= target
l = bisect_left(arr, target)
return r, n - l
# Driver code
arr = [1, 2, 8, 10, 11, 12, 19]
key = 0
res = getMoreAndLess(arr, key)
print(res[0], res[1])
Output
0 7
;;