Constructing an array of smaller elements than the corresponding elements based on input array in JavaScript

In JavaScript, constructing an array where each element represents the count of smaller numbers to the right is a common algorithmic problem. This technique is useful for data analysis, ranking systems, and competitive programming challenges.

Problem Statement

Given an input array of numbers, create an output array where each element represents the count of numbers smaller than the current element and located to its right in the input array.

Sample Input:

Input Array: [5, 2, 6, 1]

Sample Output:

Output Array: [2, 1, 1, 0]

For element 5: two numbers (2, 1) are smaller and to the right. For element 2: one number (1) is smaller and to the right. For element 6: one number (1) is smaller and to the right. For element 1: no numbers are smaller to the right.

Using Nested Loops (Brute Force)

The simplest approach uses two nested loops to compare each element with all elements to its right:

function countSmallerNumbersToRight(inputArray) {
   const outputArray = [];
   
   for (let i = 0; i < inputArray.length; i++) {
      let count = 0;
      for (let j = i + 1; j < inputArray.length; j++) {
         if (inputArray[j] < inputArray[i]) {
            count++;
         }
      }
      outputArray.push(count);
   }
   return outputArray;
}

const arr = [6, 2, 8, 5, 1, 3];
console.log("Input:", arr);
console.log("Output:", countSmallerNumbersToRight(arr));
Input: [ 6, 2, 8, 5, 1, 3 ]
Output: [ 4, 1, 3, 2, 0, 0 ]

Using Binary Indexed Tree (Fenwick Tree)

For better performance with larger arrays, use a Binary Indexed Tree to efficiently count smaller elements:

function countSmallerNumbersToRight(inputArray) {
   function updateBIT(BIT, index, value) {
      while (index < BIT.length) {
         BIT[index] += value;
         index += index & -index;
      }
   }
   
   function queryBIT(BIT, index) {
      let count = 0;
      while (index > 0) {
         count += BIT[index];
         index -= index & -index;
      }
      return count;
   }

   const maxElement = Math.max(...inputArray);
   const BIT = new Array(maxElement + 1).fill(0);
   const outputArray = [];

   for (let i = inputArray.length - 1; i >= 0; i--) {
      outputArray.unshift(queryBIT(BIT, inputArray[i] - 1));
      updateBIT(BIT, inputArray[i], 1);
   }
   return outputArray;
}

const arr = [6, 2, 8, 5, 1, 3];
console.log("Input:", arr);
console.log("Output:", countSmallerNumbersToRight(arr));
Input: [ 6, 2, 8, 5, 1, 3 ]
Output: [ 4, 1, 3, 2, 0, 0 ]

Using Binary Search Tree

A BST approach processes elements from right to left, maintaining counts of smaller elements:

class Node {
   constructor(value) {
      this.value = value;
      this.leftCount = 0;
      this.left = null;
      this.right = null;
   }
}

function insert(node, value, count, outputArray) {
   if (value < node.value) {
      node.leftCount++;
      if (node.left === null) {
         node.left = new Node(value);
         outputArray.unshift(count);
      } else {
         insert(node.left, value, count, outputArray);
      }
   } else {
      count += node.leftCount;
      if (value > node.value) {
         count++;
      }
      if (node.right === null) {
         node.right = new Node(value);
         outputArray.unshift(count);
      } else {
         insert(node.right, value, count, outputArray);
      }
   }
}

function countSmallerNumbersToRight(inputArray) {
   const outputArray = [];
   const root = new Node(inputArray[inputArray.length - 1]);
   outputArray.push(0);
   
   for (let i = inputArray.length - 2; i >= 0; i--) {
      insert(root, inputArray[i], 0, outputArray);
   }
   return outputArray;
}

const arr = [6, 2, 8, 5, 1, 3];
console.log("Input:", arr);
console.log("Output:", countSmallerNumbersToRight(arr));
Input: [ 6, 2, 8, 5, 1, 3 ]
Output: [ 4, 1, 3, 2, 0, 0 ]

Performance Comparison

Method Time Complexity Space Complexity Best For
Nested Loops O(n²) O(1) Small arrays, simple implementation
Binary Indexed Tree O(n log k) O(k) Large arrays with bounded values
Binary Search Tree O(n log n) O(n) Large arrays, balanced performance

Conclusion

Choose the nested loops approach for simplicity and small datasets. For larger arrays, Binary Indexed Tree or BST methods provide better performance with O(n log n) or O(n log k) time complexity respectively.

Updated on: 2026-03-15T23:19:00+05:30

200 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements