LintCode 613: High Five (MinHeap)

本文介绍了一种算法,用于从学生记录中找出每位学生的前五高分,并计算其平均值。通过使用最小堆(min-heap),确保了高效地找到每个学生最高五个成绩,即使学生分数数量不一。示例代码演示了如何使用C++ STL容器实现这一功能。
  1. High Five
    There are two properties in the node student id and scores, to ensure that each student will have at least 5 points, find the average of 5 highest scores for each person.

Example
Example 1:

Input:
[[1,91],[1,92],[2,93],[2,99],[2,98],[2,97],[1,60],[1,58],[2,100],[1,61]]
Output:
1: 72.40
2: 97.40

Example 2:

Input:
[[1,90],[1,90],[1,90],[1,90],[1,90],[1,90]]
Output:
1: 90.00

解法1:
利用min-heap,每个学生都分配要给min-heap (size = 5)。
记得最后算平均值的时候,priority-queue是不能用iterator或auto进行遍历的,只能看top(),然后pop()。C++ STL的容器里面只有vector/queue/deque/set/map之类的才能用iterator遍历,priority-queue好像不行 。
注意:
1)求前k个最大的值最好用最小堆(这样堆的size()就是k就可以了)。如果用最大堆,堆的size()要是n。
代码同步在
https://github.com/luqian2017/Algorithm

/**
 * Definition for a Record
 * class Record {
 * public:
 *   int id, score;
 *   Record(int id, int score) {
 *     this->id = id;
 *     this->score = score;
 *   }
 * };
 */
class Solution {
public:
    /**
     * @param results a list of <student_id, score>
     * @return find the average of 5 highest scores for each person
     * map<int, double> (student_id, average_score)
     */
    map<int, double> highFive(vector<Record>& results) {
        int len = results.size();
        
        map<int, priority_queue<int, vector<int>, greater<int>> > mp; //id, min-heap
        map<int, double> result;  //id, average-top-five
        for (int i = 0; i < len; ++i) {
            int studentId = results[i].id;
            int studentScore = results[i].score;
            mp[studentId].push(studentScore);
            //get the largest 5 elements
            if (mp[studentId].size() > 5)
                mp[studentId].pop();
        }
        
        for (auto m : mp) {
            double sum = 0;
            while(m.second.size() > 0) {
                sum += m.second.top();
                m.second.pop();
            }
            result[m.first] = sum / 5; //strictly speacking, it needs to check if the student has >= 5 courses
        }
        return result;
    }
};
根据系列源代码编写相关伪代码#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct HuffmanNode { char data; int freq; struct HuffmanNode *left, *right; } HuffmanNode; typedef struct { int size; int capacity; HuffmanNode **array; } MinHeap; HuffmanNode* newNode(char data, int freq) { HuffmanNode* node = (HuffmanNode*)malloc(sizeof(HuffmanNode)); node->data = data; node->freq = freq; node->left = node->right = NULL; return node; } MinHeap* createMinHeap(int capacity) { MinHeap* minHeap = (MinHeap*)malloc(sizeof(MinHeap)); minHeap->size = 0; minHeap->capacity = capacity; minHeap->array = (HuffmanNode**)malloc(capacity * sizeof(HuffmanNode*)); return minHeap; } void swapHuffmanNode(HuffmanNode** a, HuffmanNode** b) { HuffmanNode* t = *a; *a = *b; *b = t; } void minHeapify(MinHeap* minHeap, int idx) { int smallest = idx; int left = 2 * idx + 1; int right = 2 * idx + 2; if (left < minHeap->size && minHeap->array[left]->freq < minHeap->array[smallest]->freq) smallest = left; if (right < minHeap->size && minHeap->array[right]->freq < minHeap->array[smallest]->freq) smallest = right; if (smallest != idx) { swapHuffmanNode(&minHeap->array[smallest], &minHeap->array[idx]); minHeapify(minHeap, smallest); } } int isSizeOne(MinHeap* minHeap) { return (minHeap->size == 1); } HuffmanNode* extractMin(MinHeap* minHeap) { HuffmanNode* temp = minHeap->array[0]; minHeap->array[0] = minHeap->array[minHeap->size - 1]; --minHeap->size; minHeapify(minHeap, 0); return temp; } int i; void insertMinHeap(MinHeap* minHeap, HuffmanNode* node) { ++minHeap->size; i = minHeap->size - 1; while (i && node->freq < minHeap->array[(i - 1) / 2]->freq) { minHeap->array[i] = minHeap->array[(i - 1) / 2]; i = (i - 1) / 2; } minHeap->array[i] = node; } void buildMinHeap(MinHeap* minHeap) { int n = minHeap->size - 1; int i; for (i = (n - 1) / 2; i >= 0; --i) minHeapify(minHeap, i); } int isLeaf(HuffmanNode* root) { return !(root->left) && !(root->right); } MinHeap* createAndBuildMinHeap(char data[], int freq[], int size) { MinHeap* minHeap = createMinHeap(size); for (i = 0; i < size; ++i) minHeap->array[i] = newNode(data[i], freq[i]); minHeap->size = size; buildMinHeap(minHeap); return minHeap; } HuffmanNode* buildHuffmanTree(char data[], int freq[], int size) { HuffmanNode *left, *right, *top; MinHeap* minHeap = createAndBuildMinHeap(data, freq, size); while (!isSizeOne(minHeap)) { left = extractMin(minHeap); right = extractMin(minHeap); top = newNode('$', left->freq + right->freq); top->left = left; top->right = right; insertMinHeap(minHeap, top); } return extractMin(minHeap); } void printCodes(HuffmanNode* root, int arr[], int top) { if (root->left) { arr[top] = 0; printCodes(root->left, arr, top + 1); } if (root->right) { arr[top] = 1; printCodes(root->right, arr, top + 1); } if (isLeaf(root)) { printf("%c: ", root->data); for (i = 0; i < top; ++i) printf("%d", arr[i]); printf("\n"); } } void HuffmanCodes(char data[], int freq[], int size) { HuffmanNode* root = buildHuffmanTree(data, freq, size); int arr[100], top = 0; printCodes(root, arr, top); } int main() { int n; char data[5]; int freq[5]; printf("请输入符号的数量(4或5): "); scanf("%d", &n); if (n != 4 && n != 5) { printf("输入的数量必须是4或5。\n"); return 1; } for (i = 0; i < n; ++i) { printf("请输入第 %d 个符号: ", i + 1); scanf(" %c", &data[i]); printf("请输入 %c 的频率: ", data[i]); scanf("%d", &freq[i]); } HuffmanCodes(data, freq, n); return 0; }
最新发布
11-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值