Given a sorted array arr[] and a positive integer D, the task is to find the minimum and the maximum number of array elements that lie over the distance of D from an array element arr[i] in either direction i.e., over the range [arr[i] – D, arr[i]] or [arr[i], arr[i] + D].
Examples:
Input arr[] = {2, 4, 7, 11, 13, 14}, D = 4 Output: 1 3 Explanation: The minimum number of array elements is included is 1 from arr[0](= 2) as the there exists only 1 element that lies over the range [-2, 2]. The minimum number of array elements is included is 3 from arr[3](= 11) as the there exists only 3 elements that lies over the range [11, 15]. Therefore, print 1, 3.
Input: arr[] = {1, 3, 5, 9, 14}, D = 5 Output: 1 3
Approach: The given problem can be solved using the Greedy Technique by using the Binary Search to the left and right of every point to check how many points can be included in the range of distance D. Follow the steps below to solve the problem:
- Initialize two variables, say min and max to store minimum and maximum elements included in a range of distance D.
- Iterate the array arr[] and for each element perform the following:
- Initialize a variable dist to calculate the number of points included in a range of distance D.
- Perform the binary search on the left of arr[i] and find a number array elements over the range [arr[i] – D, arr[i]] using the following steps:
- Initialize left = 0, right = i – 1 and at every iteration:
- Find the value of mid = (left + right) / 2.
- If arr[mid] < arr[i] – D, then update the value of left to mid + 1. Otherwise, update the value of dist to mid and update the value of right to mid – 1.
- Update the value of min and max according to the value of dist.
- Perform the binary search on the left of arr[i] and find the number of array elements over the range [arr[i], arr[i] + D] using the following steps:
- Initialize left = i + 1, right = N – i and at every iteration:
- Find the value of mid = (left + right) / 2.
- If arr[mid] > arr[i] + D, then update the value of right to mid – 1. Otherwise, update the value of dist to mid and update the value of left to mid + 1.
- Update the value of min and max according to the value of dist.
- After completing the above steps, print the value of min and max as the resultant minimum and the maximum number of points covered.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int leftSearch( int arr[], int val, int i)
{
if (i == 0)
return 1;
int left = 0, right = i - 1;
int ind = -1;
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] < val) {
left = mid + 1;
}
else {
right = mid - 1;
ind = mid;
}
}
return ind != -1 ? i - ind + 1 : 1;
}
int rightSearch( int arr[], int val, int i, int N)
{
if (i == (N - 1))
return 1;
int left = i + 1;
int right = N - 1;
int ind = -1;
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] > val) {
right = mid - 1;
}
else {
left = mid + 1;
ind = mid;
}
}
return ind != -1 ? ind - i + 1 : 1;
}
vector< int > minMaxRange( int arr[], int D, int N)
{
int mx = 1, mn = N;
for ( int i = 0; i < N; i++) {
int dist = leftSearch(arr, arr[i] - D, i);
mn = min(mn, dist);
mx = max(mx, dist);
dist = rightSearch(arr, arr[i] + D, i, N);
mn = min(mn, dist);
mx = max(mx, dist);
}
vector< int > v;
v.push_back(mn);
v.push_back(mx);
return v;
}
int main()
{
int arr[] = { 1, 3, 5, 9, 14 };
int N = 5;
int D = 4;
vector< int > minMax = minMaxRange(arr, D, N);
cout << minMax[0] << " " << minMax[1] << endl;
return 0;
}
|
Java
import java.io.*;
import java.lang.Math;
import java.util.*;
class GFG {
public static int [] minMaxRange(
int [] arr, int D, int N)
{
int max = 1 , min = N;
for ( int i = 0 ; i < N; i++) {
int dist = leftSearch(
arr, arr[i] - D, i);
min = Math.min(min, dist);
max = Math.max(max, dist);
dist = rightSearch(
arr, arr[i] + D, i);
min = Math.min(min, dist);
max = Math.max(max, dist);
}
return new int [] { min, max };
}
public static int leftSearch(
int [] arr, int val, int i)
{
if (i == 0 )
return 1 ;
int left = 0 , right = i - 1 ;
int ind = - 1 ;
while (left <= right) {
int mid = (left + right) / 2 ;
if (arr[mid] < val) {
left = mid + 1 ;
}
else {
right = mid - 1 ;
ind = mid;
}
}
return ind != - 1 ? i - ind + 1 : 1 ;
}
public static int rightSearch(
int [] arr, int val, int i)
{
if (i == arr.length - 1 )
return 1 ;
int left = i + 1 ;
int right = arr.length - 1 ;
int ind = - 1 ;
while (left <= right) {
int mid = (left + right) / 2 ;
if (arr[mid] > val) {
right = mid - 1 ;
}
else {
left = mid + 1 ;
ind = mid;
}
}
return ind != - 1 ? ind - i + 1 : 1 ;
}
public static void main(String[] args)
{
int [] arr = { 1 , 3 , 5 , 9 , 14 };
int N = arr.length;
int D = 4 ;
int [] minMax = minMaxRange(arr, D, N);
System.out.print(
minMax[ 0 ] + " " + minMax[ 1 ]);
}
}
|
Python3
def minMaxRange(arr, D, N):
Max = 1
Min = N
for i in range (N):
dist = leftSearch(arr, arr[i] - D, i)
Min = min ( Min , dist)
Max = max ( Max , dist)
dist = rightSearch(arr, arr[i] + D, i)
Min = min ( Min , dist)
Max = max ( Max , dist)
return [ Min , Max ]
def leftSearch(arr, val, i):
if (i = = 0 ):
return 1
left = 0
right = i - 1
ind = - 1
while (left < = right):
mid = (left + right) / / 2
if (arr[mid] < val):
left = mid + 1
else :
right = mid - 1
ind = mid
return i - ind + 1 if ind ! = - 1 else 1
def rightSearch(arr, val, i):
if (i = = len (arr) - 1 ):
return 1
left = i + 1
right = len (arr) - 1
ind = - 1
while (left < = right):
mid = (left + right) / / 2
if (arr[mid] > val):
right = mid - 1
else :
left = mid + 1
ind = mid
return ind - i + 1 if ind ! = - 1 else 1
arr = [ 1 , 3 , 5 , 9 , 14 ]
N = len (arr)
D = 4
minMax = minMaxRange(arr, D, N)
print (f "{minMax[0]} {minMax[1]}" )
|
C#
using System;
class GFG
{
public static int [] minMaxRange( int [] arr, int D, int N)
{
int max = 1, min = N;
for ( int i = 0; i < N; i++)
{
int dist = leftSearch(
arr, arr[i] - D, i);
min = Math.Min(min, dist);
max = Math.Max(max, dist);
dist = rightSearch(
arr, arr[i] + D, i);
min = Math.Min(min, dist);
max = Math.Max(max, dist);
}
return new int [] { min, max };
}
public static int leftSearch(
int [] arr, int val, int i)
{
if (i == 0)
return 1;
int left = 0, right = i - 1;
int ind = -1;
while (left <= right)
{
int mid = (left + right) / 2;
if (arr[mid] < val)
{
left = mid + 1;
}
else
{
right = mid - 1;
ind = mid;
}
}
return ind != -1 ? i - ind + 1 : 1;
}
public static int rightSearch(
int [] arr, int val, int i)
{
if (i == arr.Length - 1)
return 1;
int left = i + 1;
int right = arr.Length - 1;
int ind = -1;
while (left <= right)
{
int mid = (left + right) / 2;
if (arr[mid] > val)
{
right = mid - 1;
}
else
{
left = mid + 1;
ind = mid;
}
}
return ind != -1 ? ind - i + 1 : 1;
}
public static void Main()
{
int [] arr = { 1, 3, 5, 9, 14 };
int N = arr.Length;
int D = 4;
int [] minMax = minMaxRange(arr, D, N);
Console.Write(minMax[0] + " " + minMax[1]);
}
}
|
Javascript
<script>
function minMaxRange(
arr, D, N) {
let max = 1, min = N;
for (let i = 0; i < N; i++) {
let dist = leftSearch(
arr, arr[i] - D, i);
min = Math.min(min, dist);
max = Math.max(max, dist);
dist = rightSearch(
arr, arr[i] + D, i);
min = Math.min(min, dist);
max = Math.max(max, dist);
}
return [min, max];
}
function leftSearch(
arr, val, i) {
if (i == 0)
return 1;
let left = 0, right = i - 1;
let ind = -1;
while (left <= right) {
let mid = Math.floor((left + right) / 2);
if (arr[mid] < val) {
left = mid + 1;
}
else {
right = mid - 1;
ind = mid;
}
}
return ind != -1 ? i - ind + 1 : 1;
}
function rightSearch(
arr, val, i) {
if (i == arr.length - 1)
return 1;
let left = i + 1;
let right = arr.length - 1;
let ind = -1;
while (left <= right) {
let mid = Math.floor((left + right) / 2);
if (arr[mid] > val) {
right = mid - 1;
}
else {
left = mid + 1;
ind = mid;
}
}
return ind != -1 ? ind - i + 1 : 1;
}
let arr = [1, 3, 5, 9, 14];
let N = arr.length;
let D = 4;
let minMax = minMaxRange(arr, D, N);
document.write(
minMax[0] + " " + minMax[1]);
</script>
|
Time Complexity: O(N*log N) Auxiliary Space: O(1)
|