剑指offer--快速排序变形(5、29)

来源:互联网 发布:问道手游刷钱软件 编辑:程序博客网 时间:2024/04/24 18:08

offer5

题目:输入n个整数,输出其中最小的k个。

例如输入123456788个数字,则最小的4个数字为1234


题目可以利用快速排序第一步来做,先选取首位的值,将小于该值的放在左边,大于等于该值的放在右边,如果该值的位置正好是k,那么该值连同左边的值就是最小的k个,如果位置小于k,那么在右边继续执行,如果大于k,那么在左边继续执行,时间复杂度平均是O(N)。

代码:


int FindPos(int *a, int low, int high){int k=a[low];int i,j;i=low;j=high;while (i<j){while (j>i && a[j]>=k)j--;a[i]=a[j];while (i<j && a[i]<k)i++;a[j]=a[i];}a[i]=k;return i;}void Find(int *a, int low, int high, int key){if (low<=high){int pos=FindPos(a, low, high);if (pos+1==key){int i=0;while (i<=pos){printf("%3d ",a[i]);i++;}printf("\n");}if (pos+1<key)Find(a, pos+1, high, key);if (pos+1>key)Find(a, low, pos-1, key);}}


还有另外一种思路,类似动态规划

首先我从头开始拿出k个值来,保存好,然后从数组读入一个新的值,如果新值比 k个值中最大值要小,那么就替换掉最大值,否则不替换,直到数组中所有数据全部读取完。k比较小时可以采用数组,k比较大值采用最大堆存储,首位就是k中的最大值,更新最大值也很方便,复杂度是O(logk)。


offer29

输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)

左右开始,然后找到左边第一个偶数和右边第一个奇数,直到左右相遇。奇偶判断可以采用位运算,最位为1那么就是奇数,否则为偶数。

代码:

void Reorder(int *a, int low, int high){if (!a || low>=high || low<0 || high<0)return;while (low<high){while (low<high && a[low]%2)low++;while (low<high && a[high]%2==0)high--;if (low<high){swap(a[low], a[high]);low++;high--;}}}


原创粉丝点击