Hackerrank challenges Median

Source: Internet
Author: User

Question Link

Median Dynamic

Max score: 67

The medianMNumbers is defined as the middle number after sorting them in order ifMIs odd or the average number of the middle 2 numbers (again after sorting) IfMIs even. You have an empty
Number list at first. Then you can add or remove some number from the list. For each add or remove operation, output the median of numbers in the list.

Example: 
For a set of M = 5 numbers, {9, 2, 8, 4, 1} the median is the third number in sorted set {1, 2, 4, 8, 9} which is 4. similarly for set of M = 4, {5, 2, 10, 4}, the median is the average of second and the third element in the sorted set {2, 4, 5, 10}
Which is (4 + 5)/2 = 4.5

Input: 
The first line is an integer n indicates the number of operations. Each of the next n lines is either "a x" or "r X" which indicates the operation is add or remove.

Output: 
For each operation: if the operation is add output the median after adding X in a single line. If the operation is remove and the number X is not in the list, output "wrong !" In a single line. If the operation is remove and the number X is in the list, output
The median after deleting X in a single line. (if the result is an integer do not output decimal point. And if the result is a double number, do not output trailing 0 s .)

Constraints: 
0 <n <= 100,000
For each "a x" or "r X", X will always be an integer which will fit in 32 bit signed integer.

Sample input:

7  r 1  a 1  a 2  a 1  r 1  r 2  r 1  

Sample output:

Wrong!  1  1.5  1  1.5  1  Wrong!

Note:As evident from the last line of the input, if after remove operation the list becomes empty you have to print "wrong !" (Quotes are for clarity ).

There are N operations. A is to add a number to the set, and R is to remove a number. Without this number, wrong is output. The median is output for each operation. If the length is even, the sum of the two numbers in the middle of the output is normal. If the length of the set is an odd number, the number in the middle is directly output. If there is no median, wrong is output. For example, the set is empty after the operation.

Idea: The method for finding the median is to sort the elements in the Set first and then obtain the result. However, we need to insert and delete the elements multiple times, so we cannot sort them every time, this method will inevitably time out.

Here I use the STL et in STL (set cannot be used because there may be duplicate elements). set can be inserted and deleted in the time complexity of O (logn, in addition, the order will be maintained during the insertion and deletion process, so that we do not need additional sorting work, which undoubtedly saves time. However, set does not seem to allow random access. At least I have not found a method for Random Access (if any ), therefore, I can only traverse the most intermediate elements through the iterator. This may be because the test samples in the following groups have timed out. Let's look at my problem-solving code, I can only say that I have only tested the first group, followed by errors and timeouts, And I want to criticize and correct them.

# Include <stdio. h ># include <set>; using namespace STD; Multiset <int> S; // you cannot use set. Please refer to the preceding int main () {int N, L; while (scanf ("% d", & N )! = EOF) {S. clear (); L = 0; char op; int X; while (n --) {int F = 1; getchar (); scanf ("% C % d ", & OP, & X); Multiset <int>: iterator it; // iterator pointer. If (OP = 'R ') {If (S. count (x) = 0) {puts ("wrong! "); F = 0;} else {It = S. find (x); S. erase (it);/* Here I want to explain why S. what about erase (x !! Because X may have multiple values, it will delete all X's */L --; If (! L) {f = 0; puts ("wrong! ") ;}} Else {S. insert (x); L ++;} If (f) {It = S. begin (); If (L = 1) {printf ("% d \ n", * It); continue;} For (INT I = 1; I <l/2; I ++) It ++; If (L % 2 = 1) {It ++; printf ("% d \ n ", * It);} else {float ans = (float) * it; it ++; ans + = (float) * it; printf ("% G \ n ", ANS/2) ;}}} return 0 ;}

I can only say that I think too much about this question. using ordinary insertion sorting can completely solve this problem, and using binary to speed up the search.

Correct Solution report

The key to this question is that the int cannot be used, because the sum of the two int may cross the border! Because this wa has been used many times. So use long.

For double, the ceil (double) function in math. h can be used to take an integer. Based on the result of Ceil (v) = V, we can judge whether V is an integer.

In terms of the output format, printf ("%. 0lf", v) indicates that the output is double and the 0 decimal places are retained.

/* Sample program illustrating input and output */#include<iostream>#include<math.h>using namespace std;long long a[100001];void getMedian(int size){    double sum = 0;    if (size % 2 == 0)    {         sum = (double(a[size/2]) + double(a[size/2-1])) / 2;    }    elsesum = a[size/2];if (ceil(sum) == sum)printf("%.0lf\n", sum);elseprintf("%.1lf\n", sum);}int findAndRemove(long long key, int size){    int begin = 0;    int end = size - 1;    while(begin <= end)    {        int mid = (begin+end)/2;        if (a[mid] < key)            begin = mid + 1;        else if (a[mid] > key)            end = mid - 1;        else        {            int i = mid;            while(i < size - 1)            {                a[i] = a[i+1];                i++;            }            return true;        }    }    return false;}int main(){    int currentSize = 0;    int n;    cin >> n;    for (int i = 0; i < n; i++)    {        char operation;        long long value;        cin >> operation >> value;        if (operation == 'r')        {            if (currentSize <= 0)                cout << "Wrong!" << endl;            else            {                if (findAndRemove(value, currentSize))                {                    currentSize--;                    if (currentSize == 0)                        cout << "Wrong!" << endl;                    else                        getMedian(currentSize);                }                else                    cout << "Wrong!" << endl;            }        }        else        {            if (currentSize == 0)                a[0] = value;            else            {                int begin = 0;                int end = currentSize - 1;                while(begin <= end)                {                    int mid = (begin+end) / 2;                    if (a[mid] < value)                        begin = mid + 1;                    else                        end = mid - 1;                }                int i = currentSize;                while(i> begin)                {                   a[i] = a[i-1];                    i--;                }                a[begin] = value;             }             currentSize++;             getMedian(currentSize);        }    }}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.