26 lines
1.3 KiB
Markdown
26 lines
1.3 KiB
Markdown
# 10.10. Rank for stream
|
|
|
|
> You are reading in a stream of integers. Periodically, you want to look up the rank of a number x (the number of values less than or equal to x). Implement the data structures and algorithms to support these operations: track (int x), called each time a number is generated, and getRankOfNumber(int x), returning the number of values less than or equal to x
|
|
|
|
Example
|
|
|
|
* Stream (in order of appearance): 5, 1, 4, 4, 5, 9, 7, 13, 3
|
|
* getRankOfNumber(1) = 0
|
|
* getRankOfNumber(3) = 1
|
|
* getRankOfNumber(4) = 3
|
|
|
|
During the streaming, the data must be saved somehow, sorted. We can create an array where at each index, the number of occurrences of that number appear. To account for all integers, we can create a dynamic array or a static array of 4B.
|
|
|
|
* First step: [0, 0, 0, 0, 1]
|
|
* Second step: [1, 0, 0, 0, 1]
|
|
* Third step: [1, 0, 0, 1, 1]
|
|
* and so on
|
|
|
|
`track(x)` just does `arr[x] += 1` if it's static, or enlarge the array and then do that. `getRankOfNumber(x)` does `sum(arr[:x])`.
|
|
|
|
## Solution
|
|
|
|
Use a binary search tree where each node stores some additional data. `track(x)` will run in O(log(n)) time, where n is the size of the tree. To find the rank of a number, we can do an in-order traversal, keeping a counter as we traverse. By the time we find `x`, `counter` will equal the number of elements less than x.
|
|
|
|
See example in book page 412.
|