getRankOfNumber(int x) 方法,返回小于或等于 x 的值的个数,等价于求下标0到当前下标的前缀和,即从0到当前下标的所有数字出现次数之和
代码
class StreamRank {
private FenwickTree fenwickTree;
public StreamRank() {
fenwickTree = new FenwickTree(50001);
}
public void track(int x) {
fenwickTree.add(x+1,1);
}
public int getRankOfNumber(int x) {
return fenwickTree.query(x+1);
}
class FenwickTree{
int[] arr;
public FenwickTree(int num){
arr = new int[num+1];
}
int lowBit(int x){
return x & ( -x );
}
public void add(int idx, int num){
while (idx < arr.length){
arr[idx] += num;
idx += lowBit(idx);
}
}
public int query(int idx){
int sum = 0;
while (idx > 0){
sum += arr[idx];
idx -= lowBit(idx);
}
return sum;
}
}
}
class MedianFinder {
PriorityQueue<Integer> left;
PriorityQueue<Integer> right;
/** initialize your data structure here. */
public MedianFinder() {
left = new PriorityQueue<>((a,b)-> b-a);
right = new PriorityQueue<>();
}
public void addNum(int num) {
if (left.size()==0||num<=left.peek()){
left.offer(num);
}else{
right.offer(num);
}
if (left.size() - right.size()>1){
right.offer(left.poll());
}else if (right.size() > left.size()){
left.offer(right.poll());
}
}
public double findMedian() {
if (left.size() == right.size()){
return ((double) (left.peek() + right.peek()))/2;
}else{
return (double)left.peek();
}
}
}