In the average case, the time complexity is , where is the length of the input array.
Key takeaways:
The "Count of Smaller Numbers After Self" problem helps in data analysis, ranking systems, and algorithm optimization.
A naive solution with two loops has O(n²) time complexity, making it inefficient for large inputs.
Using Binary Search Trees (BST) or Binary Indexed Trees (BIT) provides a more efficient O(n log n) time complexity.
The solution involves iterating from right to left, inserting elements into the BST, and counting smaller elements.
The algorithm efficiently maintains order and counts smaller numbers using BST properties.
The “Count of Smaller Numbers After Self” problem is valuable for applications in data analysis, ranking systems, and algorithm development. It helps in scenarios like tracking how many elements are smaller than a given number in a dataset or comparing scores in competitive environments. This problem also provides useful practice in advanced techniques such as divide-and-conquer, binary search, and segment trees, which are important for optimizing performance in various computational tasks.
In this Answer, we will create an array where each element represents the count of numbers smaller than it to its right in the input array.
Given an integer array nums
, return a new integer array counts
, where counts[i]
is the number of smaller elements to the right of nums[i]
.
Constraints:
nums.length
nums.length
Let’s take a look at a few examples to get a better understanding of the problem statement:
A simple approach would be to use two loops, comparing each element to all elements to its right. This, however, results in a time complexity of
A better approach would be to use a data structure like Binary Indexed Tree (BIT) or Binary Search Tree (BST), achieving a more favorable time complexity of
Here’s how the algorithm works:
Start with an empty BST.
Iterate over the input array in reverse order, i.e., from right to left.
For each number, insert it into the BST while tracking how many numbers are smaller to its right.
Use the smaller
property of BST nodes to compute the count efficiently.
Finally, we get the result list where each entry corresponds to the count of numbers smaller than the respective entry in nums
to its right.
Let’s define a Node
class that we’ll use for our Binary Search Tree. This Node
class will hold the node’s value, a count of nodes in the left subtree, and references to the left and right child nodes.
class Node:def __init__(self, val, smaller=0, left=None, right=None):self.val = valself.smaller = smaller # number of smaller elements in the left subtreeself.left = leftself.right = right
Next, we will implement the count_smaller
function, which contains the core logic to construct the BST using the Node
class and solve the problem.
def count_smaller(nums):def insert(node, val, result, i):if not node:return Node(val), resultif val <= node.val:node.left, result = insert(node.left, val, result, i)node.smaller += 1else:node.right, result = insert(node.right, val, result, i)result[i] += node.smaller + 1return node, resultresult = [0] * len(nums)root = Nonefor i in reversed(range(len(nums))):root, result = insert(root, nums[i], result, i)return result# Driver codedef main():test_cases = [# Test Case 1: Standard array with distinct values([5, 2, 6, 1], [2, 1, 1, 0]),# Test Case 2: Array with duplicates([3, 3, 1, 2], [2, 2, 0, 0]),# Test Case 3: Array with all decreasing values([5, 4, 3, 2, 1], [4, 3, 2, 1, 0]),# Test Case 4: Array with all increasing values([1, 2, 3, 4, 5], [0, 0, 0, 0, 0]),# Test Case 5: Single element array([7], [0])]print("Testing count_smaller function:\n")for i, (nums, expected) in enumerate(test_cases, 1):result = count_smaller(nums)print(f"Test Case {i}:")print(f"Input: {nums}")print(f"Output: {result}")print(f"Expected: {expected}")print(f"Pass: {result == expected}\n")# Run the test casesmain()
This approach works efficiently because the BST maintains a sorted order of elements as we iterate. For each insertion:
If the number is smaller or equal to the current node, increment the smaller
counter and move left.
If the number is greater, add the smaller
count from the node plus one (for the node itself) to the result and move right.
The time complexity of the solution is
The space complexity is
To further strengthen your coding skills and boost your technical interview preparation, here are some LeetCode problems to practice:
Also, you can explore these courses designed specifically to help you ace technical interviews:
Moreover, if you’re confident in your preparation, consider trying Educative’s AI-powered mock interviews. Mock interviews are excellent for building confidence, sharpening problem-solving skills, and identifying areas to improve before the actual interview.
Haven’t found what you were looking for? Contact Us
Free Resources