You are given an integer array nums and you have to return a new counts array. The counts array has the property where ​​counts[i]​​ is the number of smaller elements to the right of ​​nums[i]​​.

Example:

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

Explanation:
To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.

Approach #1: C++. [Fenwick Tree / Binary Indexed Tree]



class FenwickTree {
public:
FenwickTree(int n): sums_(n+1, 0) {}

void update(int i, int delta) {
while (i < sums_.size()) {
sums_[i] += delta;
i += lowbit(i);
}
}

int query(int i) const {
int sum = 0;
while (i > 0) {
sum += sums_[i];
i -= lowbit(i);
}
return sum;
}
private:
static inline int lowbit(int x) { return x & (-x); }
vector<int> sums_;
};

class Solution {
public:
vector<int> countSmaller(vector<int>& nums) {
set<int> sorted(nums.begin(), nums.end());
unordered_map<int, int> ranks;

int rank = 0;

for (const int num : sorted)
ranks[num] = ++rank;

vector<int> ans;
FenwickTree tree(ranks.size());

for (int i = nums.size() - 1; i >= 0; --i) {
ans.push_back(tree.query(ranks[nums[i]] - 1));
tree.update(ranks[nums[i]], 1);
}

std::reverse(ans.begin(), ans.end());
return ans;
}
};


  

Prefix sums of frequencise, convert the number to its rank as in sorted array.

For example:

Input:    [5, 2, 6, 1]

sorted:  [1, 2, 5, 6]

ranks:   [1, 4, 2, 3]

Increase the freq[rank] by 1.

Num  

Rank  

Freq  

Prefix sum / Query(rank - 1)  

-

-

[0, 0, 0, 0, 0]  

-

1

1

[0, 1, 0, 0, 0]

0

6

4

[0, 1, 0, 0, 1]

1

2

2

[0, 1, 1, 0, 1]

1

5

3

[0, 1, 1, 1, 1]

2

 

 

 


 Approach #2: Java. [BST]




class Solution {

class Node {
Node left, right;
int val, sum, dup = 1;
public Node(int v, int s) {
val = v;
sum = s;
}
}

public List<Integer> countSmaller(int[] nums) {
Integer[] ans = new Integer[nums.length];
Node root = null;
for (int i = nums.length - 1; i >= 0; i--) {
root = insert(nums[i], root, ans, i, 0);
}
return Arrays.asList(ans);
}

private Node insert(int num, Node node, Integer[] ans, int i, int preSum) {
if (node == null) {
node = new Node(num, 0);
ans[i] = preSum;
} else if (node.val == num) {
node.dup++;
ans[i] = preSum + node.sum;
} else if (node.val > num) {
node.sum++;
node.left = insert(num, node.left, ans, i, preSum);
} else {
node.right = insert(num, node.right, ans, i, preSum + node.dup + node.sum);
}
return node;
}
}


  


 


永远渴望,大智若愚(stay hungry, stay foolish)