3.7归并排序
需要用到辅助数组,中间分界后,左右指针进行比较,小的那个就放进current,然后右移一位。然后对
代码实现:
3.8题解:调整数组顺序,使奇数在前偶数在后
解题思路一:用归并排序,创建相同的临时数组,指针从左到右扫描,遇到奇数放进数组左边(左指针加一),遇到偶数放进数组右边(右指针减一)。
思路二:用双向分区扫描法(见快排那篇文章),左指针扫描到第一个偶数后停下,右指针扫描到第一个奇数后停下,此时交换左右指针指向的元素,重复上述操作直到右指针的位置小于左指针(并排且交错)。
3.9求出乱序数组中第K小的数
思路一:先排序再找。可以使用任意一种排序方式来对数组进行排序,但时间复杂度不一。
思路二(时间复杂度为O(n) ):使用双向扫描分区法。设置主元,将数组排序一次后比较K与主元的大小,然后对相应分区继续排序
3.10哪个数字超过了一半
统计某个元素的数量,超过数组长度的一半就输出这个元素
简单题,思路一:排序,然后输出arr.length/2的元素
思路二:排序,对连续出现的元素进行计数,然后输出
3.11发帖水王
思路:两两消除,排序后从左往右统计,设置候选值它的统计量,如果相邻的元素不相同那么就把统计量-1,如果统计量归0则更新候选值,直到得出有最大统计量的候选值(消除完后仍是正的)。
代码实现:
加强版水王:
重点在于两两消除和水王占一半的理解,因为水王占一半,去掉最后一个元素后candidate肯定不是0,因此这个candidate就是没消除的水王。
3.13最小可用ID
找出非负自然数组(乱序)中最小的可填入数字的位置。
如[1,2,4,6]最小可填入数字的坑位为3
思路一:排序,然后顺序扫描,返回第一个与数组元素不匹配的下标。时间复杂度为nlogn
思路二:分组排序。q是实际上中间位置的值,t是期望值,如果期望值小于实际值,那么就说明左半边区间中有空缺,那么只需要递归搜索左半边即可,反之搜索右半边。时间复杂度为
代码实现: