Count of Smaller Number before itself
Give you an integer array (index from 0 to n-1, where n is the size of this array, value from 0 to 10000) . For each element Ai in the array, count the number of element before this element Ai is smaller than it and return count number array.
Example
For array [1,2,7,8,5]
, return [0,1,2,3,2]
Think
- Segment Tree
- Initial with the range (0 to 10000)
- Count array elements included in a certain tree node
- Dynamic count and make a query.
- Query a value, evaluate the value and node's middle value,
- if larger, that means the left node's count should be included and also enter into the right node;
- if less, just enter the left node;
- recursive until touch the null node;
Solution
class SegmentTree{
Node root;
public SegmentTree(){
root = build(0, 20000);
}
public Node build(int left, int right) {
if(right < left)
return null;
if(left == right)
return new Node(left, right);
int m = left + ((right - left)>>1);
Node cur = new Node(left, right);
cur.leftNode = build(left, m);
cur.rightNode = build(m+1, right);
return cur;
}
public void count(int val){
count(root, val);
}
private void count(Node node, int val) {
if(node == null)
return;
int m = node.left + ((node.right - node.left)>>1);
node.cnt++;
if(val > m)
count(node.rightNode, val);
else
count(node.leftNode, val);
}
public int query(int val){
return query(root, val);
}
private int query(Node node, int val) {
int cnt = 0;
if(node == null)
return cnt;
int m = node.left + ((node.right - node.left)>>1);
cnt += (node.leftNode != null ? node.leftNode.cnt : 0);
if(val > m) // if larger:
return cnt + query(node.rightNode, val);
else // if less or equal: includes val == m
return query(node.leftNode, val);
}
}
class Node{
int left, right;
long cnt;
Node leftNode, rightNode;
public Node(int left, int right){
this.cnt = 0;
this.left = left;
this.right = right;
}
}
public class Solution {
/**
* @param A: An integer array
* @return: Count the number of element before this element 'ai' is
* smaller than it and return count number array
*/
SegmentTree tree;
public ArrayList<Integer> countOfSmallerNumberII(int[] A) {
tree = new SegmentTree();
ArrayList<Integer> res = new ArrayList<>();
for(int i = 0; i < A.length; i++) {
tree.count(A[i]);
res.add(tree.query(A[i]));
}
return res;
}
}