案例一
小范围排序练习题
已知一个几乎有序的数组,几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离不超过k,并且k相对于数组长度来说很小。请问选择什么方法对其排序比较好
分析:
1、时间复杂度为O(N平方)的排序算法
冒泡排序和选择排序,与原始序列顺序无关,都要执行那么多次,时间复杂度严格为O(N平方)
插入排序与原始序列顺序有关,每个元素移动距离不差过k,插入排序时间复杂度为 O(N*K),且K很小
2、时间复杂度为O(N*logN)的排序算法
快速排序和归并排序与原始序列顺序无关,时间复杂度严格为O(N*logN)
结果:
最优的是改进后的堆排序
移动不超过k,说明最小值位于0~k-1中,将0~k-1组成个最小堆。弹出堆顶元素,将位置k上的数放置堆顶,再次调整小根堆。递归实现。实际上采取的是改进后的堆排序的算法,时间复杂度为O(nlogk)
案例二
重复值判断练习题
判断数组中是否有重复值, 请设计一个高效算法,判断数组中是否有重复值,必须保证额外空间复杂度为O(1)。给定一个int数组A及它的大小n,请返回它是否有重复值。
解题思路:
如果没有空间复杂度限制:
可以用哈希表实现,遍历数组的过程中统计每个元素出现的个数。时间复杂度为O(N),空间复杂度为O(N)
先进行排序,后判断。
再比较相邻元素。选择时间复杂度为O(nlogn)的堆排序
案例三
有序数组合并练习题
把两个有序数组合并为一个有序数组。第一个数组空间正好可以容纳两个数组的元素。
A:2 4 6 空 空 空
B:1 3 5
输出:A: 1 2 3 4 5 6
该题核心:从后向前覆盖数组A,保证数组A有用信息不会被覆盖掉
解题思路:
(1)将第二个数组中的元素依次append进第一个数组,然后再采取一种排序方式,这个就非常简单了
(2)另一种就是A和B的最大值放到A的最后,依次转移A无序部分和 B剩余部分的最大值到A的有序部分。