Given an infinite input of integers (or others), find the following things:
The sum of the last
kelementsThe average (mean) of the last
kelementsThe minimum of the last
kelementsThe maximum of the last
kelementsThe median of the last
kelements
Sum
Well, there are two ways of thinking this, first is the sum of last k elements can be stored in a single primitive type. In this case, we store the last k elements and keep a cache of the ksum.
1 | auto it = input.begin(); |
If the sum can not be stored, we can define a new ksum class to store the sum by combining the values. The basic idea of that class is, instead of storing the sum directly, we store m partial sums for the k elements.
Mean
To calculate the mean we will use the ksum we have in previous section and divide it by k.
Minimum
To get the minimum, we can traverse through lastK and find the minimum value, which costs O(k) time, if we want O(logk) time, we can keep a minHeap but the space cost may double if we also want O(logk) insertion time.
Here is a findMin O(logk) but insert/delete O(k) example:
1 | class minHeap { |
Maximum
Maximum is similar to minimum
Median
Median is the hardest one, we need to keep two heaps, one uses for the smallest 1~(k/2) elements, one for the other (k/2 + 1) ~ k elements. The first heap is max heap because we want the largest number in the first part which can be the candidate of the median; the second heap is a min heap because we want the smallest number in the second part which can be the candidate of the median.
The algorithm works as follows:
- if there is no valid median (at the beginning), we put the input at
median - if the input is larger/equal to median, insert it into right min heap, otherwise insert it into left max heap
- if the size difference is larger than 2, we pop the top of the heap that has the larger size, and then put median into the other heap