2388 — Who’s in the Middle(解題報告)

來源:互聯網
上載者:User

http://poj.org/problem?id=2388

問題是要從未經過排序的數組中找到中位元。很多人說這題是水題。其實此題不水。只不過測試的資料水了點。應該讓排序的代碼都逾時,就沒人說水題了。

這題的思想是用快排劃分的思想。即數組中以一個數字為分水嶺,如果大於該數的數字和小於該數的數字數量相等,則該數就是我們要求的中位元。這樣演算法的時間複雜度是O(n),最差為O(n^2),通過排序的話快排是O(n*lgn),通過小根堆對前一半的資料排序的話是O(n/2*lgn)。相比之下,快排劃分的演算法優缺點都可以看出來了。

當然隨著資料量的增加,當主存無法放下全部的資料的時候,這時應該選擇用小根堆排序。因為這時必然要用到外存,而外存的io速度。。。你懂得。

這時使用小根堆只需要掃描資料一遍。(聽說面試時,很多人問)

#include<stdio.h>#include<string.h>#include<iostream>void swap(int* arr, int x,int y){int temp = arr[x];arr[x] = arr[y];arr[y] = temp;}int partition(int* arr, int begin, int end){int i, j;i = begin;long pivot = arr[begin];for(j=begin+1; j<=end; j++)if(arr[j] <= pivot)swap(arr, ++i, j);swap(arr, i, begin);return i;}int select(int* arr, int begin, int end, int i){if(begin == end)return arr[begin];int p = partition(arr, begin, end);int k = p - begin + 1;if( k == i )return  arr[p];else if(k < i)return select( arr, p+1, end, i - k);elsereturn select( arr, begin , p - 1, i);}int main(){int n;std::cin>>n;int q = 0;int* arr = new int[n];for(int i = 0; i < n; i++)std::cin>>arr[i];std::cout<<select(arr, 0, n - 1, (n + 1)/2  )<<std::endl;delete []arr;return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.