For each in 1st array count less than or equal to it in 2nd array (original) (raw)

Given two unsorted arrays a[] and b[]. Both arrays may contain duplicate elements. For each element in a[], find the count of elements in b[] are less than or equal to that element.

**Examples:

**Input: a[] = [1, 2, 3, 4, 7, 9], b[] = [0, 1, 2, 1, 1, 4]
**Output: [4, 5, 5, 6, 6, 6]
**Explanation:
For a[0] = 1, there are 4 elements in b (0, 1, 1, 1) that are ≤ 1.
For a[1] = 2, there are 5 elements in b (0, 1, 1, 1, 2) that are ≤ 2.
For a[2] = 3, there are 5 elements in b that are ≤ 3.
Similarly, for a[3] = 4, there are 6 elements in b that are ≤ 4, and for a[4] = 7 and a[5] = 9, there are also 6 elements in b that are ≤ 7 and ≤ 9, respectively.

**Input: a[] = [4, 8, 7, 5, 1], b[] = [4, 48, 3, 0, 1, 1, 5]
**Output: [5, 6, 6, 6, 3]
**Explanation:
For a[0] = 4, there are 5 elements in b (4, 3, 0, 1, 1) that are ≤ 4.
For a[1] = 8 and a[2] = 7, there are 6 elements in b that are ≤ 8 and ≤ 7.
For a[3] = 5, there are 6 elements in b that are ≤ 5.
For a[4] = 1, there are 3 elements in b (0, 1, 1) that are ≤ 1.

Table of Content

[Naive Approach] Using Nested Loops - O(n * m) Time and O(n) Space

The idea is to use two loops, the outer loop iterates through each element in array a[], and for every element in a[], the inner loop traverses array b[] to count how many elements in b[] are less than or equal to the current element from a[].

C++ `

#include #include using namespace std;

vector countLessEq(vector& a, vector& b) {

int n = a.size(), m = b.size();

// to store the result
vector<int> res(n);

// outer loop for each element of a[]
for (int i = 0; i < n; i++) {
    int count = 0;

    // inner loop for each element of b[]
    for (int j = 0; j < m; j++)
        if (b[j] <= a[i])
            count++;

    res[i] = count;
}

return res;

}

int main() { vector a = {1, 2, 3, 4, 7, 9}; vector b = {0, 1, 2, 1, 1, 4}; vector result = countLessEq(a, b); for (int i : result) { cout << i << " "; } return 0; }

Java

import java.util.*;

class GfG {

// to store the result
public static ArrayList<Integer> countLessEq(int[] a, int[] b) {
    int n = a.length, m = b.length;

    // to store the result
    ArrayList<Integer> res = new ArrayList<>();

    // outer loop for each element of a[]
    for (int i = 0; i < n; i++) {
        int count = 0;

        // inner loop for each element of b[]
        for (int j = 0; j < m; j++)
            if (b[j] <= a[i])
                count++;

        res.add(count);
    }

    return res;
}

public static void main(String[] args) {
    int[] a = {1, 2, 3, 4, 7, 9};
    int[] b = {0, 1, 2, 1, 1, 4};
    ArrayList<Integer> result = countLessEq(a, b);
    for (int i : result) {
        System.out.print(i + " ");
    }
}

}

Python

def countLessEq(a, b): n = len(a) m = len(b)

# to store the result
res = [0] * n

# outer loop for each element of a[]
for i in range(n):
    count = 0

    # inner loop for each element of b[]
    for j in range(m):
        if b[j] <= a[i]:
            count += 1

    res[i] = count

return res

if name == "main": a = [1, 2, 3, 4, 7, 9] b = [0, 1, 2, 1, 1, 4] result = countLessEq(a, b) for i in result: print(i, end=" ")

C#

using System; using System.Collections.Generic;

class GfG {

public static List<int> countLessEq(int[] a, int[] b) {
    int n = a.Length, m = b.Length;

    // to store the result
    List<int> res = new List<int>();

    // outer loop for each element of a[]
    for (int i = 0; i < n; i++) {
        int count = 0;

        // inner loop for each element of b[]
        for (int j = 0; j < m; j++)
            if (b[j] <= a[i])
                count++;

        res.Add(count);
    }

    return res;
}

public static void Main(string[] args) {
    int[] a = {1, 2, 3, 4, 7, 9};
    int[] b = {0, 1, 2, 1, 1, 4};
    List<int> result = countLessEq(a, b);
    foreach (int i in result) {
        Console.Write(i + " ");
    }
}

}

JavaScript

function countLessEq(a, b) { let n = a.length, m = b.length;

// to store the result
let res = new Array(n);

// outer loop for each element of a[]
for (let i = 0; i < n; i++) {
    let count = 0;

    // inner loop for each element of b[]
    for (let j = 0; j < m; j++)
        if (b[j] <= a[i])
            count++;

    res[i] = count;
}

return res;

}

let a = [1, 2, 3, 4, 7, 9]; let b = [0, 1, 2, 1, 1, 4]; let result = countLessEq(a, b); console.log(result.join(" "));

`

[Better Approach - 1] Using Sorting - O((n + m) * log m) Time and O(n) Space

The idea is to sort the elements of array b[], then perform a modified binary search on array b[]. For each element **x of array a[], find the last index of the largest element smaller than or equal to **x in sorted array b[]. The index of the largest element will give the count of elements.

C++ `

#include #include #include using namespace std;

// to perform the binary search int binarySearch(vector &arr, int x) { int low = 0, high = arr.size() - 1;

while (low <= high) {
    int mid = low + (high - low) / 2;
    if (arr[mid] <= x)
        low = mid + 1;
    else
        high = mid - 1;
}
return low;

}

vector countLessEq(vector& a, vector& b) { int n = a.size(), m = b.size();

// to store the result
vector<int> res(n);

// sort the array b[]
sort(b.begin(), b.end());

// outer loop for each element of a[]
for (int i = 0; i < n; i++) {
    res[i] = binarySearch(b, a[i]);
}

return res;

}

int main() { vector a = {1, 2, 3, 4, 7, 9}; vector b = {0, 1, 2, 1, 1, 4}; vector result = countLessEq(a, b); for (int i : result) { cout << i << " "; } return 0; }

Java

import java.util.*;

class GfG {

// to perform the binary search
static int binarySearch(int[] arr, int x) {
    int low = 0, high = arr.length - 1;

    while (low <= high) {
        int mid = low + (high - low) / 2;
        if (arr[mid] <= x)
            low = mid + 1;
        else
            high = mid - 1;
    }
    return low;
}

static ArrayList<Integer> countLessEq(int[] a, int[] b) {
    int n = a.length, m = b.length;

    // to store the result
    ArrayList<Integer> res = new ArrayList<>();

    // sort the array b[]
    Arrays.sort(b);

    // outer loop for each element of a[]
    for (int i = 0; i < n; i++) {
        res.add(binarySearch(b, a[i]));
    }

    return res;
}

public static void main(String[] args) {
    int[] a = {1, 2, 3, 4, 7, 9};
    int[] b = {0, 1, 2, 1, 1, 4};
    ArrayList<Integer> result = countLessEq(a, b);
    for (int i : result) {
        System.out.print(i + " ");
    }
}

}

Python

to perform the binary search

def binarySearch(arr, x): low = 0 high = len(arr) - 1

while low <= high:
    mid = low + (high - low) // 2
    if arr[mid] <= x:
        low = mid + 1
    else:
        high = mid - 1
return low

to store the result

def countEleLessThanOrEqual(a, b): n = len(a) m = len(b)

# to store the result
res = [0] * n

# sort the array b[]
b.sort()

# outer loop for each element of a[]
for i in range(n):
    res[i] = binarySearch(b, a[i])
return res

if name == "main": a = [1, 2, 3, 4, 7, 9] b = [0, 1, 2, 1, 1, 4] result = countEleLessThanOrEqual(a, b) for i in result: print(i, end=" ")

C#

using System; using System.Collections.Generic;

class GfG {

// to perform the binary search
static int binarySearch(int[] arr, int x) {
    int low = 0, high = arr.Length - 1;

    while (low <= high) {
        int mid = low + (high - low) / 2;
        if (arr[mid] <= x)
            low = mid + 1;
        else
            high = mid - 1;
    }
    return low;
}

// to store the result
static List<int> countLessEq(int[] a, int[] b) {
    int n = a.Length, m = b.Length;

    // to store the result
    List<int> res = new List<int>();

    // sort the array b[]
    Array.Sort(b);

    // outer loop for each element of a[]
    for (int i = 0; i < n; i++) {
        res.Add(binarySearch(b, a[i]));
    }

    return res;
}

public static void Main(string[] args) {
    int[] a = {1, 2, 3, 4, 7, 9};
    int[] b = {0, 1, 2, 1, 1, 4};
    List<int> result = countLessEq(a, b);
    foreach (int i in result) {
        Console.Write(i + " ");
    }
}

}

JavaScript

// to perform the binary search function binarySearch(arr, x) { let low = 0, high = arr.length - 1;

while (low <= high) {
    let mid = low + Math.floor((high - low) / 2);
    if (arr[mid] <= x)
        low = mid + 1;
    else
        high = mid - 1;
}
return low;

}

function countLessEq(a, b) { let n = a.length, m = b.length;

// to store the result
let res = new Array(n);

// sort the array b[]
b.sort((x, y) => x - y);

// outer loop for each element of a[]
for (let i = 0; i < n; i++) {
    res[i] = binarySearch(b, a[i]);
}

return res;

}

let a = [1, 2, 3, 4, 7, 9]; let b = [0, 1, 2, 1, 1, 4]; let result = countLessEq(a, b); console.log(result.join(" "));

`

[Better Approach - 2] Using Inbuilt Function - O((n + m) * log m) Time and O(n) Space

Instead of implementing the binary search in the above approach, we can use inbuilt function upper bound in C++ (and bisect_right in Python) that returns the first index **ind in the array where the value arr[ind] > target.

C++ `

#include #include #include using namespace std;

vector countLessEq(vector& a, vector& b) { int n = a.size(), m = b.size();

// to store the result
vector<int> res(n);

// sort the array b[]
sort(b.begin(), b.end());

// outer loop for each element of a[]
for (int i = 0; i < n; i++) {
    res[i] = upper_bound(b.begin(), 
    b.end(), a[i]) - b.begin();
}

return res;

}

int main() { vector a = {1, 2, 3, 4, 7, 9}; vector b = {0, 1, 2, 1, 1, 4}; vector result = countLessEq(a, b); for (int i : result) { cout << i << " "; } return 0; }

Java

import java.util.*;

class GfG {

// to perform upper_bound functionality
static int upperBound(int[] arr, int x) {
    int low = 0, high = arr.length;
    while (low < high) {
        int mid = low + (high - low) / 2;
        if (arr[mid] <= x)
            low = mid + 1;
        else
            high = mid;
    }
    return low;
}

// to store the result
public static ArrayList<Integer> countLessEq(int[] a, int[] b) {
    int n = a.length, m = b.length;

    // sort the array b[]
    Arrays.sort(b);

    // outer loop for each element of a[]
    ArrayList<Integer> res = new ArrayList<>();
    for (int i = 0; i < n; i++) {
        res.add(upperBound(b, a[i]));
    }

    return res;
}

public static void main(String[] args) {
    int[] a = {1, 2, 3, 4, 7, 9};
    int[] b = {0, 1, 2, 1, 1, 4};
    ArrayList<Integer> result =  countLessEq(a, b);
    for (int i : result) {
        System.out.print(i + " ");
    }
}

}

Python

def countLessEq(a, b): n = len(a) m = len(b)

# sort the array b[]
b.sort()

# to store the result
res = [0] * n

# outer loop for each element of a[]
for i in range(n):
    # bisect_right is equivalent to upper_bound
    import bisect
    res[i] = bisect.bisect_right(b, a[i])
return res

if name == "main": a = [1, 2, 3, 4, 7, 9] b = [0, 1, 2, 1, 1, 4] result = countLessEq(a, b) for i in result: print(i, end=" ")

C#

using System; using System.Collections.Generic;

class GfG {

// to perform upper_bound functionality
static int UpperBound(int[] arr, int x) {
    int low = 0, high = arr.Length;
    while (low < high) {
        int mid = low + (high - low) / 2;
        if (arr[mid] <= x)
            low = mid + 1;
        else
            high = mid;
    }
    return low;
}


public static List<int> countLessEq(int[] a, int[] b) {
    int n = a.Length, m = b.Length;

    // sort the array b[]
    Array.Sort(b);

    // outer loop for each element of a[]
    List<int> res = new List<int>();
    for (int i = 0; i < n; i++) {
        res.Add(UpperBound(b, a[i]));
    }

    return res;
}

public static void Main(string[] args) {
    int[] a = {1, 2, 3, 4, 7, 9};
    int[] b = {0, 1, 2, 1, 1, 4};
    List<int> result = countLessEq(a, b);
    foreach (int i in result) {
        Console.Write(i + " ");
    }
}

}

JavaScript

// to perform upper_bound functionality function upperBound(arr, x) { let low = 0, high = arr.length; while (low < high) { let mid = low + Math.floor((high - low) / 2); if (arr[mid] <= x) low = mid + 1; else high = mid; } return low; }

function countLessEq(a, b) { let n = a.length, m = b.length;

// sort the array b[]
b.sort((x, y) => x - y);

// outer loop for each element of a[]
let res = new Array(n);
for (let i = 0; i < n; i++) {
    res[i] = upperBound(b, a[i]);
}

return res;

}

let a = [1, 2, 3, 4, 7, 9]; let b = [0, 1, 2, 1, 1, 4]; let result = countLessEq(a, b); console.log(result.join(" "));

`

[Better Approach - 3] Using Sorting and Two Pointers - O(n*logn + m*logm) Time and O(n) Space

The core idea is to first pair each element of a[] with its original index and sort the array based on values. Similarly, b[] is sorted to enable efficient traversal. Using a two-pointer approach, we iterate through b[] just once, incrementing the pointer whenever the current element in b[] is less than or equal to the current element in a[]. This gives us the count of such elements efficiently. Finally, the count is stored at the original index of the corresponding element in a[], ensuring the result maintains the initial ordering of a[].

C++ `

#include #include #include using namespace std;

vector countLessEq(vector& a, vector& b) { int n = a.size(), m = b.size();

// To store the final result
vector<int> res(n);  

// Pair of (value, original_index) for sorting
vector<pair<int, int>> sortedA;  

// Attach original indices to values for array a[]
for (int i = 0; i < n; i++) {
    sortedA.push_back({a[i], i});
}

// Sort a[] (with index tracking) and b[]
sort(sortedA.begin(), sortedA.end());
sort(b.begin(), b.end());

int ind = 0;  

// For each element in sorted a[], 
// count elements in b[] less than or equal to it
for (int i = 0; i < n; i++) {
    
    // Move pointer while current b element is <= current a element
    while (ind < m && b[ind] <= sortedA[i].first) {
        ind++;
    }

    // Store result at the original index of current a element
    res[sortedA[i].second] = ind;
}

return res;

}

int main() { vector a = {1, 2, 3, 4, 7, 9}; vector b = {0, 1, 2, 1, 1, 4};

vector<int> result = countLessEq(a, b);

for (int count : result) {
    cout << count << " ";
}

return 0;

}

Java

import java.util.*;

class GfG {

public static ArrayList<Integer> countLessEq(int[] a, int[] b) {
    int n = a.length, m = b.length;

    // To store the final result, initialized to 0s
    ArrayList<Integer> res = new ArrayList<>(Collections.nCopies(n, 0));

    // Create a list of pairs (value, original index) from a[]
    List<int[]> sortedA = new ArrayList<>();
    for (int i = 0; i < n; i++) {
        sortedA.add(new int[]{a[i], i});
    }

    // Sort sortedA by value, and sort b[]
    sortedA.sort(Comparator.comparingInt(p -> p[0]));
    Arrays.sort(b);

    int ind = 0;

    // Traverse each element in sorted a[]
    for (int[] pair : sortedA) {
        int val = pair[0];
        int origIndex = pair[1];

        // Count how many elements in b[] are <= current a element
        while (ind < m && b[ind] <= val) {
            ind++;
        }

        // Store the count at the original index of a[]
        res.set(origIndex, ind);
    }

    return res;
}

public static void main(String[] args) {
    int[] a = {1, 2, 3, 4, 7, 9};
    int[] b = {0, 1, 2, 1, 1, 4};

    ArrayList<Integer> result = countLessEq(a, b);

    for (int count : result) {
        System.out.print(count + " ");
    }
}

}

Python

def countLessEq(a, b): n = len(a) m = len(b)

# Result array to store counts, initialized with zeros
res = [0] * n

# Pair each element of a[] with its original index to preserve order
aIndexed = [(val, idx) for idx, val in enumerate(a)]

# Sort the paired array and b[]
aIndexed.sort()
b.sort()

ind = 0  # Pointer for b[]

# For each element in sorted a[]
for val, originalIndex in aIndexed:
    
    # Move ind until b[ind] > current val
    while ind < m and b[ind] <= val:
        ind += 1
    # Store the count at the correct position
    res[originalIndex] = ind

return res

Driver Code

if name == "main": a = [1, 2, 3, 4, 7, 9] b = [0, 1, 2, 1, 1, 4] result = countLessEq(a, b)

print(" ".join(map(str, result)))

C#

using System; using System.Collections.Generic;

class GfG {

public static List<int> countLessEq(int[] a, int[] b) {
    int n = a.Length, m = b.Length;

    // Result list initialized with zeros
    List<int> res = new List<int>(new int[n]);

    // Create a list of pairs (value, originalIndex) for array a[]
    List<(int val, int idx)> sortedA = new List<(int, int)>();
    for (int i = 0; i < n; i++) {
        sortedA.Add((a[i], i));
    }

    // Sort a[] based on values, and b[]
    sortedA.Sort((x, y) => x.val.CompareTo(y.val));
    Array.Sort(b);

    int ind = 0;

    // For each element in sorted a[]
    foreach (var item in sortedA) {
        int value = item.val;
        int originalIndex = item.idx;

        // Move ind while b[ind] <= value
        while (ind < m && b[ind] <= value) {
            ind++;
        }

        // Store count at the correct index
        res[originalIndex] = ind;
    }

    return res;
}

public static void Main(string[] args) {
    int[] a = {1, 2, 3, 4, 7, 9};
    int[] b = {0, 1, 2, 1, 1, 4};

    List<int> result = countLessEq(a, b);

    // Output the result
    foreach (int count in result) {
        Console.Write(count + " ");
    }
}

}

JavaScript

function countLessEq(a, b) { const n = a.length, m = b.length;

// Result array initialized with zeros
const res = new Array(n).fill(0);

// Create a new array of pairs [value, originalIndex] for array a
const sortedA = a.map((val, idx) => [val, idx]);

// Sort sortedA by values and b[] in ascending order
sortedA.sort((x, y) => x[0] - y[0]);
b.sort((x, y) => x - y);

let ind = 0; 

// For each element in sortedA
for (let i = 0; i < n; i++) {
    const [value, originalIndex] = sortedA[i];

    // Count how many elements in b[] are <= value
    while (ind < m && b[ind] <= value) {
        ind++;
    }

    // Store the result at the correct original index
    res[originalIndex] = ind;
}

return res;

}

// Driver Code const a = [1, 2, 3, 4, 7, 9]; const b = [0, 1, 2, 1, 1, 4];

const result = countLessEq(a, b); console.log(result.join(" "));

`

[Expected Approach for Small Range] Using Count Array and Prefix Sum - O(n + m + max(b[i])) Time and O(max(b[i])) Space

The main idea is to first construct a frequency array for b[] to record how often each number appears. This frequency array is then transformed into a prefix sum array, where each index holds the total count of elements in b[] that are less than or equal to that index. With this preprocessed data, the count for any element in a[] can then be retrieved in constant time.

**Illustration:

C++ `

#include #include #include using namespace std;

vector countLessEq(vector& a, vector& b) {

int n = a.size(), m = b.size();

// to store the result
vector<int> res(n);

int maxi = *max_element(b.begin(), b.end());

// to store frequency of elements in b[]
vector<int> cnt(maxi + 1, 0);
for (int i = 0; i < m; i++) {
    cnt[b[i]]++;
}

// transform cnt[] to prefix sum array
for (int i = 1; i < maxi+1; i++) {
    cnt[i] += cnt[i - 1];
}

// loop for each element of a[]
for (int i = 0; i < n; i++) {
    res[i] = cnt[min(a[i], maxi)];
}

return res;

}

int main() { vector a = {1, 2, 3, 4, 7, 9}; vector b = {0, 1, 2, 1, 1, 4}; vector result = countLessEq(a, b); for (int i : result) { cout << i << " "; } return 0; }

Java

import java.util.*;

class GfG {

// to store the result
public static ArrayList<Integer> countLessEq(int[] a, int[] b) {
    int n = a.length, m = b.length;
    
    int maxi = 0;
    // to store the result
    ArrayList<Integer> res = new ArrayList<>();
    for (int i = 0; i < n; i++) {
        res.add(0);
    }
    
    for(int i=0;i<m;i++){
        maxi = Math.max(maxi, b[i]);
    }
    // to store frequency of elements in b[]
    int[] cnt = new int[maxi+1];
    for (int i = 0; i <= maxi; i++) {
        cnt[i] = 0;
    }
    for (int i = 0; i < m; i++) {
        cnt[b[i]]++;
    }

    // transform cnt[] to prefix sum array
    for (int i = 1; i <= maxi; i++) {
        cnt[i] += cnt[i - 1];
    }

    // loop for each element of a[]
    for (int i = 0; i < n; i++) {
        res.set(i, cnt[Math.min(a[i],maxi)]);
    }

    return res;
}

public static void main(String[] args) {
    int[] a = {1, 2, 3, 4, 7, 9};
    int[] b = {0, 1, 2, 1, 1, 4};
    ArrayList<Integer> result = countLessEq(a, b);
    for (int i : result) {
        System.out.print(i + " ");
    }
}

}

Python

to store the result

def countLessEq(a, b): n = len(a) m = len(b)

# to store the result
res = [0] * n
maxi = max(b)
# to store frequency of elements in b[]
cnt = [0] * (maxi + 1)

for i in range(m):
    cnt[b[i]] += 1

# transform cnt[] to prefix sum array
for i in range(1, (maxi + 1)):
    cnt[i] += cnt[i - 1]

# loop for each element of a[]
for i in range(n):
    res[i] = cnt[min(a[i], maxi)]

return res

if name == "main": a = [1, 2, 3, 4, 7, 9] b = [0, 1, 2, 1, 1, 4] result = countLessEq(a, b) for i in result: print(i, end=" ")

C#

using System; using System.Collections.Generic;

class GfG {

public static List<int> countLessEq(int[] a, int[] b) {
    int n = a.Length, m = b.Length;

    // to store the result
    List<int> res = new List<int>();
    for (int i = 0; i < n; i++) {
        res.Add(0);
    }
    int maxi = 0;
    
    for(int i=0;i<m;i++){
        maxi = Math.Max(maxi, b[i]);    
    }
    // to store frequency of elements in b[]
    int[] cnt = new int[maxi + 1];
    for (int i = 0; i < (maxi + 1); i++) {
        cnt[i] = 0;
    }
    for (int i = 0; i < m; i++) {
        cnt[b[i]]++;
    }

    // transform cnt[] to prefix sum array
    for (int i = 1; i < (maxi + 1); i++) {
        cnt[i] += cnt[i - 1];
    }

    // loop for each element of a[]
    for (int i = 0; i < n; i++) {
        res[i] = cnt[Math.Min(a[i], maxi)];
    }

    return res;
}

public static void Main(string[] args) {
    int[] a = {1, 2, 3, 4, 7, 9};
    int[] b = {0, 1, 2, 1, 1, 4};
    List<int> result = countLessEq(a, b);
    foreach (int i in result) {
        Console.Write(i + " ");
    }
}

}

JavaScript

function countLessEq(a, b) { let n = a.length, m = b.length;

// to store the result
let res = new Array(n).fill(0);

let maxi = 0;

for(let i=0;i<m;i++){
    maxi = Math.max(maxi, b[i]);
}
// to store frequency of elements in b[]
let cnt = new Array(maxi + 1).fill(0);
for (let i = 0; i < m; i++) {
    cnt[b[i]]++;
}

// transform cnt[] to prefix sum array
for (let i = 1; i <= maxi; i++) {
    cnt[i] += cnt[i - 1];
}

// loop for each element of a[]
for (let i = 0; i < n; i++) {
    res[i] = cnt[Math.min(a[i], maxi)];
}

return res;

}

// Driver Code let a = [1, 2, 3, 4, 7, 9]; let b = [0, 1, 2, 1, 1, 4]; let result = countLessEq(a, b); console.log(result.join(" "));

`