程序员面试金典-面试题 10.10. 数字流的秩

题目:

假设你正在读取一串整数。每隔一段时间,你希望能找出数字 x 的秩(小于或等于 x 的值的个数)。请实现数据结构和算法来支持这些操作,也就是说:

实现 track(int x) 方法,每读入一个数字都会调用该方法;

实现 getRankOfNumber(int x) 方法,返回小于或等于 x 的值的个数。

注意:本题相对原题稍作改动

示例:

输入:
["StreamRank", "getRankOfNumber", "track", "getRankOfNumber"]
[[], [1], [0], [0]]
输出:
[null,0,null,1]
提示:

x <= 50000
track 和 getRankOfNumber 方法的调用次数均不超过 2000 次

分析:

使用二分搜索树,节点额外存储该数字出现的次数,初始为1.

程序:

class StreamRank {
    private class Node{
        public Node left, right;
        int val;
        int nums;
        public Node(int val){
            this.val = val;
            nums = 1;
            left = null;
            right = null;
        }
    }
    private Node root;

    public StreamRank() {
        root = null;
    }
    
    public void track(int x) {
        root = add(root, x);
    }
    public Node add(Node node, int x) {
        if(node == null){
            return new Node(x);
        }
        if(x < node.val){
            node.left = add(node.left, x);
        }else if(x > node.val){
            node.right = add(node.right, x);
        }else{
            node.nums++;
        }
        return node;
    }
    
    public int getRankOfNumber(int x) {
        return find(root, x);
    }
    private int find(Node node, int x){
        if(node == null)
            return 0;
        int res = 0;
        if(node.val <= x){
            res += node.nums;
            res += find(node.right, x);
        }
        res += find(node.left, x);
        return res;
    }
}

/**
 * Your StreamRank object will be instantiated and called as such:
 * StreamRank obj = new StreamRank();
 * obj.track(x);
 * int param_2 = obj.getRankOfNumber(x);
 */

 

posted @ 2020-03-13 18:26  silentteller  阅读(367)  评论(0编辑  收藏  举报