Count of Smaller Numbers After Self — BIT + Coordinate Compress

Sanjeev SharmaSanjeev Sharma
1 min read

Advertisement

Problem

For each element, count how many elements to its right are smaller.


Approach — BIT + Coordinate Compression

  1. Coordinate compress values to indices [1..n]
  2. Process from right to left: query BIT for sum [1..rank-1], then update rank
  3. BIT stores count of elements seen so far

Time: O(n log n) | Space: O(n)


Solutions

Python

class Solution:
    def countSmaller(self, nums: list[int]) -> list[int]:
        sorted_unique=sorted(set(nums))
        rank={v:i+1 for i,v in enumerate(sorted_unique)}
        n=len(sorted_unique)
        bit=[0]*(n+1)
        def update(i):
            while i<=n: bit[i]+=1; i+=i&(-i)
        def query(i):
            s=0
            while i>0: s+=bit[i]; i-=i&(-i)
            return s
        result=[]
        for num in reversed(nums):
            r=rank[num]
            result.append(query(r-1))
            update(r)
        return result[::-1]

C++

class Solution {
    vector<int> bit; int n;
    void upd(int i){for(;i<=n;i+=i&-i)bit[i]++;}
    int qry(int i){int s=0;for(;i>0;i-=i&-i)s+=bit[i];return s;}
public:
    vector<int> countSmaller(vector<int>& nums){
        vector<int> sorted=nums; sort(sorted.begin(),sorted.end());
        sorted.erase(unique(sorted.begin(),sorted.end()),sorted.end());
        n=sorted.size(); bit.assign(n+1,0);
        auto rank=[&](int v){return lower_bound(sorted.begin(),sorted.end(),v)-sorted.begin()+1;};
        vector<int> res;
        for(int i=nums.size()-1;i>=0;i--){int r=rank(nums[i]);res.push_back(qry(r-1));upd(r);}
        reverse(res.begin(),res.end()); return res;
    }
};

Complexity

  • Time: O(n log n) | Space: O(n)

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro