leetcode 703. 数据流中的第K大元素 最小堆解法 c语言
如題:
設計一個找到數據流中第K大元素的類(class)。注意是排序后的第K大元素,不是第K個不同的元素。 你的?KthLargest?類需要一個同時接收整數?k 和整數數組nums?的構造器,它包含數據流中的初始元素。每次調用?KthLargest.add, 返回當前數據流中第K大的元素。 示例:int k = 3; int[] arr = [4,5,8,2]; KthLargest kthLargest = new KthLargest(3, arr); kthLargest.add(3);? ?// returns 4 kthLargest.add(5);? ?// returns 5 kthLargest.add(10);? // returns 5 kthLargest.add(9);? ?// returns 8 kthLargest.add(4);? ?// returns 8這道題本意是將一堆數排好序好取第K大的值,剛開始使用二叉搜索樹進行排序結果超時。后來改成歸并排序,超出時間空間。然后修改成快速排序,還是超時,最后是快排加上冒泡排序,才運行通過,即便如此,耗時超過276ms,看了下c寫的最好解法耗時僅48ms,相差N倍。它采用的是最小堆排序,空間復雜度僅需O(k)。
其實像這類海量數據中找前K大的數或者前K小的數,最合適的算法就是堆排序了。堆排序又分為大頂堆和小頂堆。大頂堆指的是節點的子節點都小于它,小頂堆指的是節點的子節點都大于它。這道題顯然是使用小頂堆,堆頂即是第K大的數,遍歷數組的時候,如果小于堆頂,可以直接丟棄,大于堆頂,則替代堆頂,然后進行堆調整動作。類似的,如果是求第K小的數,那就用大頂堆實現,堆頂即是第K小的數,遇到比堆頂大的數直接丟棄,遇到比堆頂小的數,替代堆頂,然后堆調整。
此外,在使用c語言實現的時候,數組下標記得從1開始,0可以不用,這樣寫可以避免很多0下標的處理。
堆排序在面試筆試題中相當常見,掌握好的話寫出來還是相當快,不懂的同學還是抓緊時間最練習幾遍。
下面是本題的C語言最小堆解法代碼:
//兩個數值互換 void swap(int *a, int *b) {if (a == b) return;*a = *a ^ *b; *b = *a ^ *b; *a = *a ^ *b; }typedef struct {int maxSize;int heapSize;int *heap; } KthLargest;int kthLargestAdd(KthLargest* obj, int val);//最小堆調整函數,表示調整s的位置。 void heapAdjust(int *heap, int s, int e) {int i = 1,j;for (j = s << 1; j <= e; j*=2){if (j < e && heap[j] > heap[j+1])j++;if (heap[j] > heap[s]) break;swap(heap+j, heap+s); s = j;}return; }//最小堆添加元素 void heapInsert(int *heap, int e, int val) {int f = 0, i;heap[e] = val;//和父節點比較f = e >> 1;while (f){if (val < heap[f]){swap(heap+e, heap+f);e = f; f = e >> 1; }elsebreak; }return; }KthLargest* kthLargestCreate(int k, int* nums, int numsSize) {int i = 0, j = 0;KthLargest* n = (KthLargest*)calloc(1, sizeof(KthLargest));n->maxSize = k;n->heapSize = 0;n->heap = (int *)calloc((k+1), sizeof(int));for (; i < numsSize; i++)kthLargestAdd(n, nums[i]);return n; }int kthLargestAdd(KthLargest* obj, int val) {int i = 0;//超出堆大小則和堆頂比較,否則插入堆尾,然后自底向上找到合適位置if (obj->heapSize < obj->maxSize){obj->heapSize++;heapInsert(obj->heap, obj->heapSize, val);}else{if(obj->heap[1] < val){obj->heap[1] = val;heapAdjust(obj->heap, 1, obj->heapSize);}}return obj->heap[1]; }void kthLargestFree(KthLargest* obj) {free(obj);return; }?
=============================================================================================
Linux應用程序、內核、驅動開發交流討論群(745510310),感興趣的同學可以加群討論、交流、資料查找等,前進的道路上,你不是一個人奧^_^。
總結
以上是生活随笔為你收集整理的leetcode 703. 数据流中的第K大元素 最小堆解法 c语言的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 农行的结息交易是什么意思
- 下一篇: 堆排序之 大顶堆和小顶堆 c语言