Given an integer array arr[], and integers idxDiff and valDiff, find whether there exists a pair of indices (i, j) such that:
- i != j
- abs(i - j) ≤ indDiff
- abs(arr[i] - arr[j]) ≤ valDiff
Return true if such a pair exists; otherwise, return false.
Examples:
Input: arr[] = [1, 2, 3, 1], idxDiff = 3, valDiff = 0
Output: true
Explanation: The pair of indices (0, 3) satisfies all the conditions: abs(0 - 3) = 3 and abs(arr[0] - arr[3]) = abs(1 - 1) = 0.
Input: arr[] = [1, 5, 9, 1, 5, 9], idxDiff = 2, valDiff = 3
Output: false
Explanation: No pair of indices satisfies both the conditions.
Table of Content
[Naive Approach] Check All Valid Pairs - O(n * idxDiff) Time O(1) Space
The idea is to check all pairs of elements whose indices differ by at most
idxDiff. For each such pair, check whether the absolute difference between their values is at mostvalDiff. If a valid pair is found, returntrue; otherwise, returnfalseafter examining all possible pairs.
#include <bits/stdc++.h>
using namespace std;
bool hasNearbyPair(vector<int> &arr, int idxDiff, int valDiff)
{
int n = arr.size();
// Check all pairs within idxDiff distance.
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n && j <= i + idxDiff; j++)
{
// Check value difference condition.
if (abs(arr[i] - arr[j]) <= valDiff)
{
return true;
}
}
}
return false;
}
// Driver Code
int main()
{
vector<int> arr = {1, 2, 3, 1};
int idxDiff = 3;
int valDiff = 0;
cout << (hasNearbyPair(arr, idxDiff, valDiff) ? "true" : "false");
return 0;
}
import java.util.Arrays;
public class GfG {
public static boolean
hasNearbyPair(int[] arr, int idxDiff, int valDiff)
{
int n = arr.length;
// Check all pairs within idxDiff distance.
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n && j <= i + idxDiff;
j++) {
// Check value difference condition.
if (Math.abs(arr[i] - arr[j]) <= valDiff) {
return true;
}
}
}
return false;
}
public static void main(String[] args)
{
int[] arr = { 1, 2, 3, 1 };
int idxDiff = 3;
int valDiff = 0;
System.out.println(
hasNearbyPair(arr, idxDiff, valDiff) ? "true"
: "false");
}
}
def hasNearbyPair(arr, idxDiff, valDiff):
n = len(arr)
# Check all pairs within idxDiff distance.
for i in range(n):
for j in range(i + 1, n):
if j > i + idxDiff:
break
# Check value difference condition.
if abs(arr[i] - arr[j]) <= valDiff:
return True
return False
# Driver Code
if __name__ == "__main__":
arr = [1, 2, 3, 1]
idxDiff = 3
valDiff = 0
print("true" if hasNearbyPair(arr, idxDiff, valDiff) else "false")
using System;
class GfG {
static bool hasNearbyPair(int[] arr, int idxDiff,
int valDiff)
{
int n = arr.Length;
// Check all pairs within idxDiff distance.
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n && j <= i + idxDiff;
j++) {
// Check value difference condition.
if (Math.Abs(arr[i] - arr[j]) <= valDiff) {
return true;
}
}
}
return false;
}
static void Main()
{
int[] arr = { 1, 2, 3, 1 };
int idxDiff = 3;
int valDiff = 0;
Console.WriteLine(
hasNearbyPair(arr, idxDiff, valDiff) ? "true"
: "false");
}
}
function hasNearbyPair(arr, idxDiff, valDiff) {
const n = arr.length;
// Check all pairs within idxDiff distance.
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n && j <= i + idxDiff; j++) {
// Check value difference condition.
if (Math.abs(arr[i] - arr[j]) <= valDiff) {
return true;
}
}
}
return false;
}
// Driver Code
const arr = [1, 2, 3, 1];
const idxDiff = 3;
const valDiff = 0;
console.log(hasNearbyPair(arr, idxDiff, valDiff)? 'true' : 'false');
Output
true
Time Complexity: O(n * idxDiff)
Auxiliary Space: O(1)
[Expected Approach] Sliding Window and Ordered Set - O(n log idxDiff) Time and O(idxDiff) Space
The idea is to maintain a sliding window of the last
idxDiffelements using an ordered set. For each element, we search for a value in the current window that lies within the range[arr[i] - valDiff, arr[i] + valDiff]. If such a value exists, a valid pair is found. The sliding window is updated by inserting the current element and removing elements that fall outside the allowed index difference range.
Let us understand with example:
Input: arr[] = [1, 2, 3, 1], idxDiff = 3, valDiff = 0
- Process 1: Set = {1}
- Process 2: No element in range [2, 2], insert 2. Set = {1, 2}
- Process 3: No element in range [3, 3], insert 3. Set = {1, 2, 3}
- Process last 1: Element 1 is found in range [1, 1].
- Valid pair found, so return true.
#include <bits/stdc++.h>
using namespace std;
bool hasNearbyPair(vector<int> &arr, int idxDiff, int valDiff)
{
// Stores elements within the current sliding window
set<int> s;
for (int i = 0; i < arr.size(); i++)
{
// Find the first element >= (arr[i] - valDiff)
auto it = s.lower_bound(arr[i] - valDiff);
// If such an element exists and lies within
// [arr[i] - valDiff, arr[i] + valDiff],
// then a valid pair is found
if (it != s.end() && *it <= arr[i] + valDiff)
return true;
// Insert current element into the window
s.insert(arr[i]);
// Remove the element that falls outside
// the allowed index difference range
if (i >= idxDiff)
s.erase(arr[i - idxDiff]);
}
// No valid pair found
return false;
}
// Driver Code
int main()
{
vector<int> arr = {1, 2, 3, 1};
int idxDiff = 3;
int valDiff = 0;
cout << (hasNearbyPair(arr, idxDiff, valDiff) ? "true" : "false");
return 0;
}
import java.util.TreeSet;
public class GfG {
public static boolean
hasNearbyPair(int[] arr, int idxDiff, int valDiff)
{
// Stores elements within the current sliding window
TreeSet<Integer> s = new TreeSet<>();
for (int i = 0; i < arr.length; i++) {
// Find the first element >= (arr[i] - valDiff)
Integer it = s.ceiling(arr[i] - valDiff);
// If such an element exists and lies within
// [arr[i] - valDiff, arr[i] + valDiff],
// then a valid pair is found
if (it != null && it <= arr[i] + valDiff)
return true;
// Insert current element into the window
s.add(arr[i]);
// Remove the element that falls outside
// the allowed index difference range
if (i >= idxDiff)
s.remove(arr[i - idxDiff]);
}
// No valid pair found
return false;
}
// Driver Code
public static void main(String[] args)
{
int[] arr = { 1, 2, 3, 1 };
int idxDiff = 3;
int valDiff = 0;
System.out.println(
hasNearbyPair(arr, idxDiff, valDiff) ? "true"
: "false");
}
}
def hasNearbyPair(arr, idxDiff, valDiff):
# Stores elements within the current sliding window
s = set()
for i in range(len(arr)):
# Find the first element >= (arr[i] - valDiff)
it = None
for num in sorted(s):
if num >= arr[i] - valDiff:
it = num
break
# If such an element exists and lies within
# [arr[i] - valDiff, arr[i] + valDiff],
# then a valid pair is found
if it is not None and it <= arr[i] + valDiff:
return True
# Insert current element into the window
s.add(arr[i])
# Remove the element that falls outside
# the allowed index difference range
if i >= idxDiff:
s.remove(arr[i - idxDiff])
# No valid pair found
return False
# Driver Code
if __name__ == "__main__":
arr = [1, 2, 3, 1]
idxDiff = 3
valDiff = 0
print("true" if hasNearbyPair(arr, idxDiff, valDiff) else "false")
using System;
using System.Collections.Generic;
public class GfG {
public static bool HasNearbyPair(int[] arr, int idxDiff,
int valDiff)
{
// Stores elements within the current sliding window
SortedSet<int> s = new SortedSet<int>();
for (int i = 0; i < arr.Length; i++) {
// Find the first element >= (arr[i] - valDiff)
int ? it = null;
foreach(int num in s)
{
if (num >= arr[i] - valDiff) {
it = num;
break;
}
}
// If such an element exists and lies within
// [arr[i] - valDiff, arr[i] + valDiff],
// then a valid pair is found
if (it.HasValue && it.Value <= arr[i] + valDiff)
return true;
// Insert current element into the window
s.Add(arr[i]);
// Remove the element that falls outside
// the allowed index difference range
if (i >= idxDiff)
s.Remove(arr[i - idxDiff]);
}
// No valid pair found
return false;
}
public static void Main()
{
int[] arr = { 1, 2, 3, 1 };
int idxDiff = 3;
int valDiff = 0;
Console.WriteLine(
HasNearbyPair(arr, idxDiff, valDiff) ? "true"
: "false");
}
}
function hasNearbyPair(arr, idxDiff, valDiff) {
// Stores elements within the current sliding window
let s = new Set();
for (let i = 0; i < arr.length; i++) {
// Find the first element >= (arr[i] - valDiff)
let it = null;
for (let num of [...s].sort((a, b) => a - b)) {
if (num >= arr[i] - valDiff) {
it = num;
break;
}
}
// If such an element exists and lies within
// [arr[i] - valDiff, arr[i] + valDiff],
// then a valid pair is found
if (it!== null && it <= arr[i] + valDiff)
return true;
// Insert current element into the window
s.add(arr[i]);
// Remove the element that falls outside
// the allowed index difference range
if (i >= idxDiff)
s.delete(arr[i - idxDiff]);
}
// No valid pair found
return false;
}
// Driver Code
let arr = [1, 2, 3, 1];
let idxDiff = 3;
let valDiff = 0;
console.log(hasNearbyPair(arr, idxDiff, valDiff)? "true" : "false");
Output
true
Time Complexity: O(n log idxDiff)
Auxiliary Space: O(idxDiff)