维护实时中位数和秩

1.实时中位数 leecode 295

/*
 * solution :
 * 1.利用PriorityQueue新建两个堆,一个大根堆maxHeap(需要自己实现比较器),一个小根堆minHeap
 * 2.插入元素时,让大根堆的堆顶元素始终小于等于中位数,小根堆的堆顶元素始终大于中位数
 * 3.所以元素个数为奇数个时,大根堆比小根堆多一个元素,且中位数为大根堆堆顶元素;元素个数为偶数时,两堆一样高,中位数为两堆顶元素的平均值
 * 4.主要是插入元素时,要根据两堆的size来与堆顶元素进行比较,决定插入哪个堆
 */
public class S295 {
    private PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(new MaxComparator());
    private PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>();
    // Adds a number into the data structure.
    public void addNum(int num) {
        if (maxHeap.size() > minHeap.size()) {
            if (num < maxHeap.peek()) {
                minHeap.offer(maxHeap.poll());
                maxHeap.offer(num);
            } else {
                minHeap.offer(num);
            }
        } else {
            if (maxHeap.size() == 0) {
                maxHeap.offer(num);
            } else {
                if (num > minHeap.peek()) {
                    maxHeap.offer(minHeap.poll());
                    minHeap.offer(num);
                } else {
                    maxHeap.offer(num);
                }
            }
        }
    }

    // Returns the median of current data stream
    public double findMedian() {
        if (maxHeap.size() == 0)
            return -1;
        if (maxHeap.size() == minHeap.size()) {
            return (double)(maxHeap.peek() + minHeap.peek()) / 2; 
        } else {
            return maxHeap.peek();
        }
    }
}
class MaxComparator implements Comparator<Integer> {
    @Override
    public int compare(Integer a, Integer b) {
        if (a > b) {
            return -1;
        } else if (a < b) {
            return 1;
        } else {
            return 0;
        }
    }
}
View Code

2.实时秩  某个数的秩是当前数组中小于等于这个数的数的个数  程序员面试金典 P267 11-8

/*
* solution:
* 维护实时秩其实就是使数组始终有序,很容易想到了二叉查找树,不过要给每个节点实时记录左子节点个数leftSize。
* 我们从二叉查找树的根节点开始查找,会出现三种情况
* 1. 当前节点值等于当前值,则当前值的秩则是当前节点的leftSize
* 2. 当前节点值大于当前值,则要往当前节点的左子节点继续查找
* 3. 当前节点值小于当前值,则当前值的秩首先得加上当前节点值的leftSize + 1(1代表当前节点本身),再往右继续查找
*/

import java.util.*;

public class Rank {
    RankNode root = null;
    public int[] getRankOfNumber(int[] A, int n) {
        // write code here
        int[] rank = new int[n];
        for (int i = 0; i < n; i++) {
            track(A[i]);
            rank[i] = root.getRank(A[i]);
        }
        return rank;
    }    
    public void track(int val) {
        if (root == null)
            root = new RankNode(val);
        else
            root.insert(val);
    }
}
class RankNode {
    RankNode left = null, right = null;
    int val = 0;
    int leftSize = 0;
    public RankNode(int val) {
        this.val = val;
    }
    public void insert(int val) {
        if (val <= this.val) {
            if (this.left != null)
                this.left.insert(val);
            else
                this.left = new RankNode(val);
            this.leftSize++;
        } else {
            if (this.right != null)
                this.right.insert(val);
            else
                this.right = new RankNode(val);
        }
    }
    public int getRank(int val) {
        if (val == this.val)
            return this.leftSize;
        if (val > this.val) {
            if(this.right == null)
                return -1;
            return this.leftSize + 1 + this.right.getRank(val);
        }
        if (this.left == null)
            return -1;
        return this.left.getRank(val);
    }
}
View Code

 

posted @ 2016-07-29 16:51  fisherinbox  阅读(543)  评论(0编辑  收藏  举报