美文网首页
LeetCode #295 Find Median from D

LeetCode #295 Find Median from D

作者: 刘煌旭 | 来源:发表于2021-04-10 01:12 被阅读0次
Median_of_Data_Stream.png
/**
* Abstract: To be added
*/
typedef struct PriorityQueueStruct {
    int capacity;
    int count;
    double *keys;
    double(*cmp)(double, double);
}*PriorityQueue;

void pq_exch(double *a, int i, int j) {
    double t = a[I];
    a[i] = a[j];
    a[j] = t;
}

int pq_max(double *a, int i, int j, double(*cmp)(double, double)) { return cmp(a[i], a[j]) > .0f ? i : j; }

void pq_swim(double *a, int k, double (*cmp)(double, double)) {
    int p = k / 2;
    while (k > 1 && cmp(a[k], a[p]) > .0f) {
        pq_exch(a, k, p);
        k = p;
        p = k / 2;
    }
}

void pq_sink(double *a, int n, int k, double(*cmp)(double, double)) {
    while (2 * k <= n) {
        int j = 2 * k;
        if (j < n && cmp(a[j], a[j + 1]) < .0f) j += 1;
        if (cmp(a[k], a[j]) >= .0f) break;
        pq_exch(a, k, j);
        k = j;
    }
}

PriorityQueue PriorityQueueCreate(double(*cmp)(double, double)) {
    PriorityQueue pq = (PriorityQueue)malloc(sizeof(*pq));
    pq->cmp = cmp;
    pq->capacity = 20000;
    pq->count = 0;
    pq->keys = malloc((pq->capacity + 1) * sizeof(double));
    return pq;
}

void PriorityQueueRelease(PriorityQueue pq) {
    free(pq->keys);
    free(pq);
}

bool PriorityQueueIsEmpty(PriorityQueue pq) { return pq->count == 0; }

void PriorityQueueInsert(PriorityQueue pq, double k) {
    pq->keys[++pq->count] = k;
    pq_swim(pq->keys, pq->count, pq->cmp);
}

double PriorityQueueDelete(PriorityQueue pq) {
    double ret = pq->keys[1];
    pq->keys[1] = pq->keys[pq->count];
    pq->keys[pq->count] = INT_MIN;
    pq->count--;
    pq_sink(pq->keys, pq->count, 1, pq->cmp);
    return ret;
}

double PriorityQueueHP(PriorityQueue pq) { return pq->keys[1]; }

double ascending_cmp(double a, double b) { return b - a; }
double descending_cmp(double a, double b) { return a - b; }

typedef struct {
    PriorityQueue leftPQ;
    PriorityQueue rightPQ;
} MedianFinder;

/** initialize your data structure here. */

MedianFinder* medianFinderCreate() {
    MedianFinder *mf = (MedianFinder*)malloc(sizeof(*mf));
    mf->leftPQ = PriorityQueueCreate(descending_cmp);
    mf->rightPQ = PriorityQueueCreate(ascending_cmp);
    return mf;
}

void medianFinderAddNum(MedianFinder* mf, double num) {
    if (mf->leftPQ->count != 0 && mf->rightPQ->count != 0) {
        if (mf->leftPQ->count > mf->rightPQ->count) {
            double min = PriorityQueueHP(mf->leftPQ);
            if (num < min) {
                PriorityQueueDelete(mf->leftPQ);
                PriorityQueueInsert(mf->leftPQ, num);
                PriorityQueueInsert(mf->rightPQ, min);
            } else {
                PriorityQueueInsert(mf->rightPQ, num);
            }
        } else {
            double min = PriorityQueueHP(mf->leftPQ);
            if (num <= min) {
                PriorityQueueInsert(mf->leftPQ, num);
            } else {
                min = PriorityQueueHP(mf->rightPQ);
                if (min >= num) {
                    PriorityQueueInsert(mf->leftPQ, num);
                } else {
                    PriorityQueueDelete(mf->rightPQ);
                    PriorityQueueInsert(mf->rightPQ, num);
                    PriorityQueueInsert(mf->leftPQ, min);
                }
            }
        }
    } else if (mf->leftPQ->count == 0) {
        PriorityQueueInsert(mf->leftPQ, num);
    } else if (mf->rightPQ->count == 0) {
        double min = PriorityQueueHP(mf->leftPQ);
        if (num < min) {
            PriorityQueueDelete(mf->leftPQ);
            PriorityQueueInsert(mf->leftPQ, num);
            PriorityQueueInsert(mf->rightPQ, min);
        } else {
            PriorityQueueInsert(mf->rightPQ, num);
        }
    }
}

double medianFinderFindMedian(MedianFinder* mf) {
    if (mf->leftPQ->count > mf->rightPQ->count) {
        return PriorityQueueHP(mf->leftPQ);
    } else {
        return (PriorityQueueHP(mf->leftPQ) + PriorityQueueHP(mf->rightPQ)) / 2.0f;
    }
}

void medianFinderFree(MedianFinder* mf) {
    PriorityQueueRelease(mf->leftPQ);
    PriorityQueueRelease(mf->rightPQ);
    free(mf);
}

相关文章

网友评论

      本文标题:LeetCode #295 Find Median from D

      本文链接:https://www.haomeiwen.com/subject/jmjgkltx.html