题目描述:
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
采用堆排比较好,但最后一个数据超时了?
update(2013.4.16):
用我面B公司时被问到的一个方法就能过,晕~~
思路:类似快排的方法,每次递归地找k个数落入哪个部分。最后在sort一个这k个数就好,
代码:
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; void partition(int*arr, int k, int start, int end){ if(start>=end) return; int left = start; int right = end; int pivot = arr[left]; while(left<right){ while(left<right && arr[right]>pivot) right--; if(left<right) arr[left++] = arr[right]; while(left<right && arr[left]<pivot) left++; if(left<right) arr[right--] = arr[left]; } arr[left] = pivot; int left_size = left-start; int right_size = end - left; //printf("left_size=%d\nright_size=%d\n\n",left_size,right_size); //恰好k个最小的数 if(left_size==k-1) return; else if(left_size<k-1){ partition(arr, k-left_size-1, left+1, end); }else{ partition(arr, k, start, left-1); } } //把最小的k个数放到数组前k个位置 void helper(int* arr, int n, int k){ partition(arr, k, 0, n-1); } int arr[200005]; int main(){ int n,k,i; while(scanf("%d %d", &n, &k)!=EOF){ for(i=0;i<n;i++){ scanf("%d", &arr[i]); } helper(arr,n,k); sort(arr, arr+k); for(i=0;i<k-1;i++) printf("%d ",arr[i]); printf("%d\n",arr[k-1]); } return 0; }
浙公网安备 33010602011771号